feat: initial Jimi Gallery prototype
- 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
This commit is contained in:
672
assets/styles.css
Normal file
672
assets/styles.css
Normal file
@ -0,0 +1,672 @@
|
||||
: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; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user