- Public site (Home/Artists/Exhibitions/News/About/Contact) with EN/KO/JA i18n - Admin panel with login, CRUD, image upload, multilingual editing - Exhibition slider/lightbox view - FastAPI + MongoDB backend, JWT auth - Docker Compose deployment, behind nginx at jimi.yakenator.io
673 lines
10 KiB
CSS
673 lines
10 KiB
CSS
:root {
|
|
--bg: #ffffff;
|
|
--fg: #111111;
|
|
--muted: #6a6a6a;
|
|
--line: #e6e6e6;
|
|
--hover: #000000;
|
|
--accent: #6b3d8f;
|
|
--accent-soft: #f3ecf7;
|
|
--max: 1440px;
|
|
--pad: 40px;
|
|
--sans: "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
--serif: "Cormorant Garamond", "Times New Roman", Times, serif;
|
|
--display: "Cinzel", "Cormorant Garamond", "Times New Roman", serif;
|
|
}
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
html,
|
|
body {
|
|
margin: 0;
|
|
padding: 0;
|
|
background: var(--bg);
|
|
color: var(--fg);
|
|
font-family: var(--sans);
|
|
font-size: 15px;
|
|
line-height: 1.5;
|
|
-webkit-font-smoothing: antialiased;
|
|
}
|
|
|
|
a {
|
|
color: inherit;
|
|
text-decoration: none;
|
|
}
|
|
|
|
a:hover {
|
|
color: var(--muted);
|
|
}
|
|
|
|
img {
|
|
display: block;
|
|
max-width: 100%;
|
|
height: auto;
|
|
}
|
|
|
|
h1,
|
|
h2,
|
|
h3,
|
|
h4 {
|
|
font-weight: 400;
|
|
margin: 0;
|
|
letter-spacing: -0.01em;
|
|
}
|
|
|
|
h1 {
|
|
font-family: var(--serif);
|
|
font-size: 64px;
|
|
line-height: 1.05;
|
|
letter-spacing: -0.02em;
|
|
}
|
|
|
|
h2 {
|
|
font-family: var(--serif);
|
|
font-size: 40px;
|
|
line-height: 1.1;
|
|
}
|
|
|
|
h3 {
|
|
font-size: 18px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
p {
|
|
margin: 0 0 1em;
|
|
}
|
|
|
|
hr {
|
|
border: 0;
|
|
border-top: 1px solid var(--line);
|
|
margin: 0;
|
|
}
|
|
|
|
/* ---------- nav ---------- */
|
|
|
|
.nav {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 50;
|
|
background: var(--bg);
|
|
border-bottom: 1px solid var(--line);
|
|
}
|
|
|
|
.nav-inner {
|
|
max-width: var(--max);
|
|
margin: 0 auto;
|
|
padding: 18px var(--pad);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 24px;
|
|
}
|
|
|
|
.brand {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
color: var(--fg);
|
|
}
|
|
|
|
.brand:hover {
|
|
color: var(--fg);
|
|
opacity: 0.85;
|
|
}
|
|
|
|
.brand-mark {
|
|
width: 34px;
|
|
height: 34px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.brand-word {
|
|
font-family: var(--display);
|
|
font-size: 17px;
|
|
letter-spacing: 0.12em;
|
|
font-weight: 500;
|
|
text-transform: uppercase;
|
|
line-height: 1;
|
|
color: var(--fg);
|
|
}
|
|
|
|
.nav-right {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 28px;
|
|
}
|
|
|
|
.nav-links {
|
|
display: flex;
|
|
gap: 28px;
|
|
font-size: 13px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.12em;
|
|
}
|
|
|
|
.lang-controls {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
.lang-reset {
|
|
background: transparent;
|
|
border: 0;
|
|
color: var(--muted);
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
padding: 2px 4px;
|
|
line-height: 1;
|
|
}
|
|
.lang-reset:hover { color: var(--fg); }
|
|
|
|
.lang-switcher {
|
|
display: inline-flex;
|
|
gap: 0;
|
|
border: 1px solid var(--line);
|
|
font-size: 11px;
|
|
letter-spacing: 0.05em;
|
|
}
|
|
.lang-switcher .lang-btn {
|
|
background: transparent;
|
|
border: 0;
|
|
padding: 4px 8px;
|
|
font: inherit;
|
|
font-size: 11px;
|
|
color: var(--muted);
|
|
cursor: pointer;
|
|
border-right: 1px solid var(--line);
|
|
text-transform: none;
|
|
}
|
|
.lang-switcher .lang-btn:last-child { border-right: 0; }
|
|
.lang-switcher .lang-btn:hover { color: var(--fg); }
|
|
.lang-switcher .lang-btn.active {
|
|
background: var(--fg);
|
|
color: #fff;
|
|
}
|
|
|
|
.nav-links a.active {
|
|
color: var(--accent);
|
|
border-bottom: 1px solid var(--accent);
|
|
padding-bottom: 2px;
|
|
}
|
|
|
|
/* ---------- layout ---------- */
|
|
|
|
main {
|
|
max-width: var(--max);
|
|
margin: 0 auto;
|
|
padding: 0 var(--pad);
|
|
}
|
|
|
|
.section {
|
|
padding: 80px 0;
|
|
}
|
|
|
|
.section-tight {
|
|
padding: 40px 0;
|
|
}
|
|
|
|
.eyebrow {
|
|
font-size: 12px;
|
|
letter-spacing: 0.15em;
|
|
text-transform: uppercase;
|
|
color: var(--muted);
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.muted {
|
|
color: var(--muted);
|
|
}
|
|
|
|
.divider {
|
|
border-top: 1px solid var(--line);
|
|
margin: 0;
|
|
}
|
|
|
|
/* ---------- hero ---------- */
|
|
|
|
.hero {
|
|
padding: 48px 0 96px;
|
|
}
|
|
|
|
.hero-image {
|
|
width: 100%;
|
|
aspect-ratio: 16 / 9;
|
|
object-fit: cover;
|
|
margin-bottom: 32px;
|
|
background: #f2f2f2;
|
|
}
|
|
|
|
.hero-meta {
|
|
display: grid;
|
|
grid-template-columns: 2fr 1fr;
|
|
gap: 40px;
|
|
align-items: end;
|
|
}
|
|
|
|
.hero-meta h1 {
|
|
max-width: 900px;
|
|
}
|
|
|
|
.hero-sub {
|
|
font-size: 14px;
|
|
color: var(--muted);
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.hero-sub strong {
|
|
color: var(--fg);
|
|
font-weight: 500;
|
|
display: block;
|
|
}
|
|
|
|
/* ---------- grids ---------- */
|
|
|
|
.grid {
|
|
display: grid;
|
|
gap: 48px 32px;
|
|
}
|
|
|
|
.grid-3 {
|
|
grid-template-columns: repeat(3, 1fr);
|
|
}
|
|
|
|
.grid-2 {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
}
|
|
|
|
.grid-4 {
|
|
grid-template-columns: repeat(4, 1fr);
|
|
}
|
|
|
|
.card-image {
|
|
width: 100%;
|
|
aspect-ratio: 4 / 5;
|
|
object-fit: cover;
|
|
background: #f2f2f2;
|
|
margin-bottom: 14px;
|
|
}
|
|
|
|
.card-image.wide {
|
|
aspect-ratio: 3 / 2;
|
|
}
|
|
|
|
.card-title {
|
|
font-size: 16px;
|
|
font-weight: 500;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.card-sub {
|
|
font-size: 13px;
|
|
color: var(--muted);
|
|
}
|
|
|
|
/* ---------- artist / exhibition detail ---------- */
|
|
|
|
.detail {
|
|
padding: 64px 0;
|
|
}
|
|
|
|
.detail-header {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 60px;
|
|
margin-bottom: 80px;
|
|
align-items: start;
|
|
}
|
|
|
|
.detail-header img {
|
|
aspect-ratio: 4 / 5;
|
|
object-fit: cover;
|
|
width: 100%;
|
|
}
|
|
|
|
.detail-text .meta {
|
|
margin-bottom: 32px;
|
|
font-size: 13px;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.detail-text .meta span + span::before {
|
|
content: "·";
|
|
margin: 0 10px;
|
|
}
|
|
|
|
.detail-text p {
|
|
font-size: 16px;
|
|
max-width: 60ch;
|
|
}
|
|
|
|
.works-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
gap: 80px 40px;
|
|
}
|
|
|
|
.work figcaption {
|
|
margin-top: 14px;
|
|
font-size: 13px;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.work figcaption strong {
|
|
display: block;
|
|
color: var(--fg);
|
|
font-weight: 500;
|
|
font-size: 14px;
|
|
margin-bottom: 2px;
|
|
}
|
|
|
|
.work img {
|
|
width: 100%;
|
|
background: #f2f2f2;
|
|
}
|
|
|
|
/* ---------- filters ---------- */
|
|
|
|
.filters {
|
|
display: flex;
|
|
gap: 24px;
|
|
margin-bottom: 40px;
|
|
font-size: 13px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.12em;
|
|
}
|
|
|
|
.filters button {
|
|
background: none;
|
|
border: 0;
|
|
padding: 0;
|
|
font: inherit;
|
|
color: var(--muted);
|
|
cursor: pointer;
|
|
letter-spacing: inherit;
|
|
text-transform: inherit;
|
|
}
|
|
|
|
.filters button.active {
|
|
color: var(--accent);
|
|
border-bottom: 1px solid var(--accent);
|
|
padding-bottom: 2px;
|
|
}
|
|
|
|
.filters button:hover {
|
|
color: var(--fg);
|
|
}
|
|
|
|
/* ---------- footer ---------- */
|
|
|
|
footer {
|
|
border-top: 1px solid var(--line);
|
|
margin-top: 120px;
|
|
padding: 48px var(--pad);
|
|
font-size: 13px;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.footer-inner {
|
|
max-width: var(--max);
|
|
margin: 0 auto;
|
|
display: grid;
|
|
grid-template-columns: 2fr 1fr 1fr 1fr;
|
|
gap: 40px;
|
|
}
|
|
|
|
.footer-inner strong {
|
|
display: block;
|
|
color: var(--fg);
|
|
font-weight: 500;
|
|
margin-bottom: 12px;
|
|
letter-spacing: 0.05em;
|
|
text-transform: uppercase;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.footer-inner a {
|
|
display: block;
|
|
margin-bottom: 6px;
|
|
}
|
|
|
|
.footer-admin {
|
|
margin-top: 32px;
|
|
padding-top: 24px;
|
|
border-top: 1px solid var(--line);
|
|
font-size: 12px;
|
|
}
|
|
|
|
/* ---------- misc ---------- */
|
|
|
|
.page-title {
|
|
padding: 60px 0 40px;
|
|
}
|
|
|
|
.page-title h1 {
|
|
font-size: 56px;
|
|
}
|
|
|
|
.about-body {
|
|
max-width: 62ch;
|
|
font-size: 18px;
|
|
line-height: 1.65;
|
|
}
|
|
|
|
.contact-grid {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 80px;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.contact-grid strong {
|
|
display: block;
|
|
font-weight: 500;
|
|
margin-bottom: 6px;
|
|
}
|
|
|
|
.news-item {
|
|
display: grid;
|
|
grid-template-columns: 1fr 2fr;
|
|
gap: 32px;
|
|
padding: 32px 0;
|
|
border-top: 1px solid var(--line);
|
|
}
|
|
|
|
.news-item:last-child {
|
|
border-bottom: 1px solid var(--line);
|
|
}
|
|
|
|
.news-item img {
|
|
aspect-ratio: 4 / 3;
|
|
object-fit: cover;
|
|
background: #f2f2f2;
|
|
}
|
|
|
|
.news-item time {
|
|
font-size: 12px;
|
|
color: var(--muted);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.1em;
|
|
display: block;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.news-item h3 {
|
|
font-family: var(--serif);
|
|
font-size: 28px;
|
|
font-weight: 400;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
/* ---------- responsive ---------- */
|
|
|
|
@media (max-width: 960px) {
|
|
:root {
|
|
--pad: 24px;
|
|
}
|
|
h1 {
|
|
font-size: 40px;
|
|
}
|
|
.grid-3,
|
|
.grid-4 {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
}
|
|
.hero-meta,
|
|
.detail-header,
|
|
.works-grid,
|
|
.news-item,
|
|
.contact-grid {
|
|
grid-template-columns: 1fr;
|
|
gap: 32px;
|
|
}
|
|
.footer-inner {
|
|
grid-template-columns: 1fr 1fr;
|
|
}
|
|
.nav-right {
|
|
gap: 16px;
|
|
}
|
|
.nav-links {
|
|
gap: 16px;
|
|
font-size: 11px;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 560px) {
|
|
.grid-3,
|
|
.grid-4,
|
|
.grid-2 {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
.footer-inner {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
.nav-links a:not(.brand) {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
/* ---------- exhibition slider (lightbox) ---------- */
|
|
.slider-trigger {
|
|
cursor: zoom-in;
|
|
}
|
|
|
|
.slider {
|
|
position: fixed;
|
|
inset: 0;
|
|
background: #000;
|
|
display: none;
|
|
z-index: 200;
|
|
color: #fff;
|
|
}
|
|
.slider.open { display: flex; flex-direction: column; }
|
|
.slider-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 18px 28px;
|
|
font-size: 12px;
|
|
letter-spacing: 0.12em;
|
|
text-transform: uppercase;
|
|
color: rgba(255,255,255,0.75);
|
|
}
|
|
.slider-header .slider-counter { font-variant-numeric: tabular-nums; }
|
|
.slider-close {
|
|
background: none;
|
|
border: 0;
|
|
color: #fff;
|
|
font-size: 22px;
|
|
cursor: pointer;
|
|
padding: 4px 8px;
|
|
line-height: 1;
|
|
}
|
|
.slider-stage {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
position: relative;
|
|
padding: 0 40px;
|
|
min-height: 0;
|
|
}
|
|
.slider-stage img {
|
|
max-width: 100%;
|
|
max-height: 100%;
|
|
object-fit: contain;
|
|
}
|
|
.slider-nav {
|
|
position: absolute;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
width: 52px;
|
|
height: 52px;
|
|
border-radius: 50%;
|
|
background: rgba(255,255,255,0.08);
|
|
border: 1px solid rgba(255,255,255,0.18);
|
|
color: #fff;
|
|
font-size: 22px;
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
.slider-nav:hover { background: rgba(255,255,255,0.16); }
|
|
.slider-nav.prev { left: 20px; }
|
|
.slider-nav.next { right: 20px; }
|
|
.slider-nav:disabled { opacity: 0.25; cursor: default; }
|
|
|
|
.slider-caption {
|
|
padding: 20px 40px 14px;
|
|
text-align: center;
|
|
font-size: 14px;
|
|
line-height: 1.5;
|
|
color: rgba(255,255,255,0.85);
|
|
}
|
|
.slider-caption strong {
|
|
display: block;
|
|
font-family: var(--serif);
|
|
font-style: italic;
|
|
font-weight: 400;
|
|
font-size: 20px;
|
|
color: #fff;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.slider-strip {
|
|
display: flex;
|
|
gap: 8px;
|
|
overflow-x: auto;
|
|
padding: 14px 28px 22px;
|
|
scrollbar-width: thin;
|
|
}
|
|
.slider-strip button {
|
|
flex-shrink: 0;
|
|
width: 64px;
|
|
height: 64px;
|
|
border: 1px solid rgba(255,255,255,0.15);
|
|
background: rgba(255,255,255,0.04);
|
|
padding: 0;
|
|
cursor: pointer;
|
|
opacity: 0.5;
|
|
transition: opacity 0.15s;
|
|
}
|
|
.slider-strip button.active {
|
|
opacity: 1;
|
|
border-color: rgba(255,255,255,0.8);
|
|
}
|
|
.slider-strip img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
display: block;
|
|
}
|
|
|
|
@media (max-width: 640px) {
|
|
.slider-stage { padding: 0 16px; }
|
|
.slider-nav { width: 42px; height: 42px; font-size: 18px; }
|
|
.slider-nav.prev { left: 8px; }
|
|
.slider-nav.next { right: 8px; }
|
|
.slider-strip { padding: 10px 14px 18px; }
|
|
.slider-strip button { width: 48px; height: 48px; }
|
|
}
|
|
|