/* ============================================================
   NILO FIELD — Artist EPK Page / Client Production (from Master Template)
   Brand Authority: ARTIST_BASE PRIMARY — Theme: LIGHT
   Design direction: Mineral / Concrete / Faceless / Spatial / Editorial
   Palette: Mineral White, Pale Concrete, Graphite text, Muted Silver accent
   Visual Configuration Layer = :root tokens (Master-supported). DOM / IA /
   interaction / breakpoints are unchanged from the Master.
============================================================= */

:root{
  /* ---- Color ---- */
  --bg:            #F2F1ED; /* Mineral White */
  --bg-deep:       #E7E5E0; /* Pale Concrete — Music/Works zone tone */
  --bg-elevated:   #FAF9F6; /* Soft Off-white */
  --bg-elevated-2: #DDDAD3;
  --border:        #C9C6BE;
  --border-soft:   #DAD8D2; /* derived: between --bg-deep and --border (not in Web Brand Configuration) */
  --boundary:      rgba(37, 39, 42, 0.12); /* Global Section Boundary — graphite @12% */

  --text-primary:   #25272A;
  --text-secondary: #666A70;
  --text-tertiary:  #92969B;

  --accent:      #A7ADB3; /* Neutral Accent — decorative lines / fills only; text-role uses are remapped in the CLIENT block at EOF */
  --accent-dim:  rgba(167, 173, 179, 0.18);
  --accent-line: rgba(167, 173, 179, 0.60);

  /* ---- Type — Premium Reference 1:1 정렬 (Patch 20260926_01 §02) ---- */
  --font-display: 'Pretendard Variable', -apple-system, BlinkMacSystemFont, 'Malgun Gothic', 'Segoe UI', sans-serif;
  --font-body:    'Pretendard Variable', -apple-system, BlinkMacSystemFont, 'Malgun Gothic', 'Segoe UI', Helvetica, Arial, sans-serif;
  --font-serif:   Georgia, 'Noto Serif KR', serif;

  /* Premium Type Scale (Patch §02) — 역할별 임의 px 난립 방지 */
  --scale-display: clamp(3rem, 5vw, 5.6rem);
  --scale-h2:      clamp(1.6rem, 3vw, 2.6rem);
  --scale-h3:      clamp(1.2rem, 2vw, 1.6rem);
  --scale-body:    1rem;
  --scale-small:   0.875rem;

  /* ---- Layout ---- */
  --content-max: 1360px;
  --text-max: 720px;
  --edge: clamp(20px, 5vw, 72px);
  --nav-height: 72px;

  /* ---- Space ---- */
  --space-section-xl: clamp(88px, 11vw, 168px);
  --space-section: clamp(64px, 9vw, 128px);
  --space-section-ml: clamp(52px, 6.5vw, 96px);
  --space-section-dense: clamp(40px, 5vw, 72px);
  --space-section-compact: clamp(28px, 3.5vw, 48px);
  --space-lg: 40px;
  --space-md: 24px;
  --space-sm: 12px;

  --radius: 2px;

  /* ---- Motion timing (STEP 05 §19 — single shared scale) ---- */
  --motion-fast: 180ms;
  --motion-standard: 380ms;
  --motion-editorial: 600ms;
  --ease-standard: cubic-bezier(.4,0,.2,1);
}

*{ box-sizing: border-box; }
/* Header가 fixed로 전환되어 문서 흐름에서 공간을 차지하지 않으므로
   (Patch 20260926_01 §05-2), 모든 anchor 이동에 --nav-height만큼
   scroll-padding을 둔다. Mobile 전용으로 좁게 잡았던 이전 #works/#video
   개별 offset은 이 전역 규칙으로 대체한다. */
html{ scroll-behavior: smooth; scroll-padding-top: var(--nav-height); }
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto; }
  *{ animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

body{
  margin: 0;
  background: var(--bg);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--scale-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  word-break: keep-all;
  overflow-wrap: break-word;
  line-break: strict;
}

a{ color: inherit; text-decoration: none; }
ul{ list-style: none; margin: 0; padding: 0; }
button{ font-family: inherit; }

img{ max-width: 100%; display: block; }

.section-inner{
  max-width: var(--content-max);
  margin: 0 auto;
  padding: 0 var(--edge);
}
.text-col{ max-width: var(--text-max); margin-left: auto; margin-right: auto; padding: 0 var(--edge); }

/* ============================================================
   TYPOGRAPHY HIERARCHY (STEP 05 §03, unified per user feedback)
   Level 1 Artist Name → .hero-name
   Level 2 Section Title → .section-title — one consistent size,
     weight, and title-to-content margin across every section (Bio,
     Music, Works, Career, Proof, Video, Press, Contact). Previously
     varied by role (--large / default / --eyebrow, each a different
     size, case treatment, and margin-bottom) — removed for a
     unified page rhythm.
   Level 3 Content Title → work/music/career/credit item titles
   Level 4 Metadata → small type/year/location strings
============================================================= */
.section-title{
  font-family: var(--font-display);
  font-size: clamp(0.85rem, 1vw + 0.6rem, 1rem);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.08em;
  color: var(--text-primary);

  position: relative;
  display: inline-block;
  padding-left: 16px;

  margin-top: 0;
  margin-bottom: var(--space-lg);
}
.section-title::before{
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  translate: 0 -50%;
  width: 9px;
  height: 1px;
  background: var(--accent);
}

section{
  /* top-only rhythm — the next section's own top padding already
     provides the visual gap, so symmetric top+bottom padding was
     doubling up at every boundary (flagged in STEP 04 Desktop QA
     as excessive empty space). */
  padding: var(--space-section) 0 clamp(24px, 3vw, 40px);
  border-top: 1px solid var(--boundary);
}
section:first-of-type{ border-top: none; }
main > section:last-of-type{ padding-bottom: var(--space-section); }

/* Section rhythm variation (STEP 05 §06, Visual Rhythm Patch 02 §18) —
   not every section uses the same vertical density. Career is pushed
   past the shared --space-section-xl scale so it reads as the bigger of
   the page's two "very large" moments; Contact stays on the shared xl
   scale for top air but gets extra bottom padding instead, since its job
   is width of closing negative space, not a taller peak. Works sits one
   step below the editorial sections around it (Medium-Large); Proof
   drops below Press's density (Medium → quieter-than-Medium) as the
   deliberate comedown right after Career's peak. Snapshot/Footer stay
   compact. Deliberately uneven so a long light page doesn't read
   as one flat repeating template. */
.snapshot{ padding: var(--space-section-compact) 0; }
/* Music entrance (Visual Rhythm Patch 02 §07-08) — a half-step more top air
   than Bio's default --space-section, so crossing into the Pale Concrete
   zone feels like a deliberate scene change, not just a tone swap at the
   same rhythm. Bottom stays close to Works so the two read as one zone. */
.music{ padding: clamp(76px, 10vw, 148px) 0 clamp(32px, 4vw, 48px); }
.works{ padding: var(--space-section-ml) 0 clamp(40px, 5vw, 64px); }
/* Career (Patch 02 §10) — the page's second visual peak. Deliberately
   larger than the shared --space-section-xl scale (which Contact also
   uses) so Career reads as the bigger of the two: more top run-up before
   the slider, more room before the list starts. */
.career{ padding: clamp(108px, 13.5vw, 208px) 0 clamp(48px, 6vw, 80px); }
.proof{ padding: clamp(32px, 4vw, 64px) 0 clamp(20px, 2.5vw, 36px); }
.press{ padding: var(--space-section-dense) 0 clamp(24px, 3vw, 40px); }
.contact{ padding: var(--space-section-xl) 0 clamp(72px, 9vw, 128px); }

/* Visual Zone tone separation (Visual Rhythm Patch §07) — four zones the
   page should read as, from top to bottom:
   Zone 01 Artist Identity  (Hero/Snapshot/Bio)      → Mineral White, Snapshot
                                                        stays a quiet elevated
                                                        info strip (unchanged)
   Zone 02 Music / Work     (Music/Works)             → Pale Concrete, a
                                                        barely-there tone shift
                                                        signalling "entering
                                                        the music section"
   Zone 03 Live/Professional(Career/Proof)            → Elevated Surface;
                                                        Career is the visual
                                                        peak, Proof the quiet
                                                        evidence zone right
                                                        after it
   Zone 04 Media / Contact  (Video/Press/Contact/Footer) → back to Mineral White,
                                                        density stepping down
                                                        toward Contact */
.snapshot, .career, .proof{ background: var(--bg-elevated); }
.music, .works{ background: var(--bg-deep); }

/* Career ambient layer (Patch §13) — current photography isn't laid in as a
   section background per the patch's Background Image Rule; a barely-there
   radial tint (neutral silver, top-weighted like stage light) is
   used instead so Career reads as the page's visual peak without becoming
   a "colour section". */
.career{
  background:
    radial-gradient(140% 90% at 50% -10%, rgba(167, 173, 179, 0.16), transparent 62%),
    var(--bg-elevated);
}
/* Title → Slider air: previously Career's title had extra margin-bottom
   beyond the shared spacing to give the slider room to breathe as its
   own moment. Removed for title-spacing uniformity (user feedback) —
   Career's overall section padding (top run-up before the title) is
   unaffected, only the title-to-content gap now matches every other
   section. */

/* ============================================================
   HEADER
============================================================= */
/* Fixed, true-transparent → scrolled-translucent header (Patch §05-2).
   Overlaps Hero; Hero top padding compensates with var(--nav-height)
   (§05-6) so content never renders under the header. */
.site-header{
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;

  height: var(--nav-height);
  background: transparent;
  /* Premium과 동일 기법 — border-bottom-color만 transparent로 두고 폭은
     1px을 유지한다. 색상은 투명이지만 fixed 헤더의 컴포지팅 레이어 경계에서
     실제로 옅은 1px 라인이 렌더링되는 것까지 Premium과 동일하게 재현한다
     (사용자 확인 — Premium 실제 렌더링에도 이 라인이 존재함, 2026-09-26). */
  border-bottom: 1px solid transparent;

  -webkit-backdrop-filter: none;
  backdrop-filter: none;

  transition:
    background var(--motion-standard) var(--ease-standard),
    border-color var(--motion-standard) var(--ease-standard),
    backdrop-filter var(--motion-standard) var(--ease-standard);
}
.site-header.is-scrolled{
  background: rgba(242, 241, 237, 0.78);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-bottom-color: var(--border);
}
.header-inner{
  max-width: var(--content-max); margin:0 auto; padding: 0 var(--edge);
  height: 100%;
  display:flex; align-items:center; justify-content:space-between; gap: 24px;
}
.wordmark{
  font-family: var(--font-display); font-weight:500;
  font-size: 1.1rem; letter-spacing: 0.02em;
  color: var(--text-primary);
}
.main-nav{ display:flex; gap: 28px; margin-left: auto; }
.main-nav a{
  font-family: var(--font-body); font-size: var(--scale-small);
  font-weight: 500; color: var(--text-primary); opacity: 1;
  transition: color var(--motion-fast) var(--ease-standard), border-color var(--motion-fast) var(--ease-standard);
}
.main-nav a:hover, .main-nav a:focus-visible{ color: var(--accent); }
.nav-toggle{ display:none; background:none; border:none; cursor:pointer; padding:8px; }
.nav-toggle span{ display:block; width:20px; height:1px; background:var(--text-primary); margin:5px 0; }

/* ============================================================
   BUTTONS
   CTA feedback (STEP 05 §17-C): one mechanism only, used everywhere —
   background/foreground inversion. No mixed hover languages.
============================================================= */
.btn{
  display:inline-flex; align-items:center; justify-content:center;
  padding: 12px 22px; font-size: 14px; font-weight: 500;
  border: 1px solid transparent; border-radius: var(--radius);
  white-space: nowrap; transition: background var(--motion-fast) var(--ease-standard),
    color var(--motion-fast) var(--ease-standard), border-color var(--motion-fast) var(--ease-standard);
}
.btn[hidden]{ display: none; }
.btn--primary{ background: var(--text-primary); color: var(--bg); }
.btn--primary:hover{ background: var(--accent); color: var(--bg); }
.btn--secondary{ border-color: var(--border); color: var(--text-primary); background: transparent; }
.btn--secondary:hover{ background: var(--text-primary); color: var(--bg); border-color: var(--text-primary); }
.btn--ghost{ color: var(--text-secondary); background: transparent; }
.btn--ghost:hover{ background: var(--text-primary); color: var(--bg); }

.btn:focus-visible{ outline: 2px solid var(--accent); outline-offset: 2px; }

/* ============================================================
   HERO
============================================================= */
.hero-inner{
  max-width: var(--content-max); margin: 0 auto;
  /* Header가 fixed로 Hero 위에 겹치므로 top padding에 --nav-height를
     포함한다 (Patch §05-6). 기존 visual composition(비율)은 유지. */
  padding: calc(clamp(40px,6vw,88px) + var(--nav-height)) var(--edge) var(--space-section);
  display:grid; grid-template-columns: minmax(0,0.9fr) minmax(0,1.1fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}
.hero-visual .asset-slot{ max-width: 420px; }

/* Text-led fallback when Hero Portrait is unavailable (STEP 04 CASE C) */
.hero-inner--textled{ grid-template-columns: 1fr; }
.hero-inner--textled .hero-copy{ max-width: 640px; }
/* Hero eyebrow — Premium accent-colored eyebrow (Patch §06-3). Left tick
   is not forced here; ordinary Section Label eyebrow (.section-title)
   keeps the tick, Hero uses the Premium Hero reference directly. */
/* Hero information typography — fixed breakpoint scale, not viewport-
   dependent clamp/vw (Patch 20260926_02 §10). Prevents Artist Name /
   eyebrow from continuing to grow on ultra-wide viewports (1680~2560). */
.hero-copy .eyebrow{
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.08em;
  color: var(--accent);
  margin: 0 0 16px;
}
.hero-name{
  font-family: var(--font-display);
  font-size: 4.5rem;
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  margin: 0 0 20px;
}
.hero-position{
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--text-secondary);
  max-width: var(--text-max);
  margin: 0 0 32px;
}
.hero-cta{ display:flex; flex-wrap: wrap; gap: 12px; }

/* Mobile-only compact profile meta line (Patch 01 §6, Option B) —
   hidden on desktop; desktop uses the separate Snapshot section instead. */
.hero-meta-mobile{
  display: none;
  font-family: var(--font-body); font-size: var(--scale-small); color: var(--text-secondary);
  margin: 0 0 24px; padding-bottom: 20px; border-bottom: 1px solid var(--border-soft);
}
.hero-meta-mobile__sep{ color: var(--text-tertiary); margin: 0 8px; }

/* Tablet (Patch §10-2) */
@media (max-width: 1024px){
  .hero-name{ font-size: 4rem; }
}

/* ============================================================
   ASSET SLOT (placeholder system)
============================================================= */
.asset-slot{
  width: 100%;
  border: 1px dashed var(--border);
  background: var(--bg-elevated);
  display:flex; align-items:center; justify-content:center;
  position: relative; overflow: hidden;
}
.asset-slot__label{
  font-family: monospace; font-size: 11px; color: var(--text-tertiary);
  letter-spacing: .02em; text-align:center; padding: 8px 12px;
  transition: opacity var(--motion-fast) var(--ease-standard);
}

/* Real image — fills the slot, object-fit per type */
.asset-slot__img{
  width: 100%; height: 100%; display:block;
  object-fit: cover; object-position: center center;
  transition: transform var(--motion-standard) var(--ease-standard);
}
.asset-slot:has(.asset-slot__img){ border-style: solid; }
.asset-slot__img--portrait{ object-position: center 22%; }
.asset-slot__img--cover{ object-position: center center; }

/* Hero portrait — no frame. Image reads directly against the
   background rather than sitting "in a card" (STEP 05 §5). */
.hero-visual .asset-slot{ border: none; background: transparent; }

/* Designed fallback surface — used when a structurally-required
   image slot (cover, thumbnail) has no asset. Never an empty box. */
.asset-slot--fallback{
  border-style: solid;
  background: radial-gradient(120% 120% at 20% 15%, var(--bg-elevated-2), var(--bg-elevated) 60%, var(--bg) 100%);
}
.asset-slot__mark{
  font-family: var(--font-serif); font-style: italic; font-size: 14px;
  letter-spacing: .08em; color: var(--text-tertiary); opacity: .5;
}

/* Image hover (STEP 05 §5/§17-B) — barely-there zoom, never a large
   zoom, glow, or tilt. Work/Video cards use their own Premium-aligned
   hover rules (no border highlight — see Selected Works / Video Media
   sections below, Patch §07-6/§09-3); this shared rule now only covers
   Music artwork. */
.music-card .asset-slot{ overflow: hidden; }
.music-card:hover .asset-slot__img{ transform: scale(1.015); }

/* ============================================================
   REVEAL ON SCROLL (STEP 05 §17-A / §19 — editorial timing,
   opacity + small Y movement only, respects reduced-motion)
============================================================= */
.reveal{
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--motion-editorial) var(--ease-standard),
              transform var(--motion-editorial) var(--ease-standard);
}
.reveal.is-visible{
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce){
  .reveal{ opacity:1; transform:none; transition:none; }
}

/* ============================================================
   SNAPSHOT — Dynamic Meta Slot (2~4 items, data-driven). Desktop only.
============================================================= */
.snapshot{ padding: var(--space-lg) 0; }
.snapshot-grid{
  display:grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-md);
}
.snapshot-item{ display:flex; flex-direction:column; gap:6px; }
.snapshot-item__label{ font-size:12px; color: var(--text-tertiary); text-transform:uppercase; letter-spacing:.05em; }
.snapshot-item__value{ font-size:14px; color: var(--text-primary); }

/* ============================================================
   BIO — Container(.section-inner)는 대표 음악/주요 작업/주요 활동과
   동일한 Wide Content Grid를 공유한다(STEP 06 §03). 본문 문장만
   .bio-text에서 가독 폭으로 제한하고, Editorial Image는 Section
   전체 폭(.section-inner)까지 그대로 확장한다.
============================================================= */
.bio-text{ max-width: var(--text-max); }
.bio-short{ font-size: 18px; color: var(--text-primary); line-height: 1.7; margin: 0 0 20px; }
.bio-toggle{
  background:none; border: 1px solid var(--border); color: var(--text-secondary);
  padding: 8px 16px; cursor:pointer; font-size: 13px; display:inline-flex; align-items:center; gap:6px;
}
.bio-toggle:hover, .bio-toggle:focus-visible{ color: var(--accent); border-color: var(--accent-line); }
.bio-more{ margin-top: 24px; display:flex; flex-direction:column; gap: 16px; }
.bio-more[hidden]{ display: none; }
.bio-more p{ color: var(--text-secondary); font-size: 15px; line-height: 1.75; margin:0; }
.bio-more em{ color: var(--text-primary); font-style: normal; }

/* Editorial image — full Section Grid width (not tied to the
   readable text column), matching Music/Works/Career visual scale.
   Native ratio(3/2) is set inline by script.js; only cap max-height
   here so the crop stays editorial rather than overwhelming at
   full section width. */
.bio-visual{ margin: var(--space-lg) 0 0; }
.bio-visual .asset-slot{ max-height: 560px; }
.bio-visual[hidden]{ display:none; }
@media (max-width: 768px){
  .bio-visual .asset-slot{ max-height: none; }
}

/* ============================================================
   MUSIC
============================================================= */
/* ============================================================
   MUSIC — Selected Music. Desktop: all 3 tracks use the same Player C+
   structure (STEP 05 §8-10, locked master direction). Mobile: Primary
   keeps Artwork+Embed, Secondary collapses to a compact listen-link row
   via `.player--secondary` overrides in the 768px breakpoint below
   (STEP 06 Production Content Patch 04 §04-07) — no separate mobile DOM.
============================================================= */
.music-list{ display:flex; flex-direction:column; gap: 16px; }

/* ---- Player C+ — Full-width Horizontal Editorial Row (STEP 06 §09) ----
   Artwork | Title/Meta | Official Embed | Platform Link, one clear row.
   Flexbox (not grid-template-areas) so it degrades gracefully when a
   track has no artwork and/or no embed/platform data yet. */
.player{
  display:flex; align-items:center; gap: 24px; flex-wrap: wrap;
  border: 1px solid var(--border); background: var(--bg-elevated);
  padding: var(--space-md) var(--space-lg);
  /* Full section width kept (no card-width cap) — leftover horizontal
     space is distributed evenly across the row's internal gaps instead
     of being dumped as one block before the CTA (Patch §02 follow-up 2). */
  justify-content: space-between;
}
.player-artwork{ flex: 0 0 104px; }
.player-artwork .asset-slot{ aspect-ratio: 1/1; }
.player-info{ flex: 0 0 auto; min-width: 150px; }
.player-info__title{ font-family: var(--font-display); font-weight: 500; font-size: 17px; margin:0 0 4px; }
.player-info__meta{ font-size: 13px; color: var(--text-tertiary); margin:0; }
/* Compact Editorial Player — embed grows to fill the row but is capped
   so it never stretches the full remaining section width (Patch §02). */
.player-embed{ flex: 1 1 400px; width: 100%; max-width: 480px; min-width: 200px; }
.music-embed__frame{ display:block; width: 100%; max-width: 100%; border-radius: 4px; }
.player-platforms{ flex: 0 0 auto; display:flex; flex-wrap: wrap; gap: 8px; }

/* No listen data yet for this track — let the title/meta breathe instead
   of leaving a lopsided empty row (URL 미확정 상태의 정상 케이스). */
.player--info-only .player-info{ flex: 1 1 auto; }
.player--info-only .player-info__title{ font-size: 20px; }

/* No-artwork variant (STEP 06 §14) — artwork block simply isn't in the
   DOM at all when there's no cover; flexbox reflows without a gap. */

.platform-btn{
  display:inline-flex; align-items:center; gap:6px;
  border: 1px solid var(--border); padding: 8px 14px; font-size: 13px;
  color: var(--text-secondary); position: relative; background: transparent;
  white-space: nowrap;
  transition: background var(--motion-fast) var(--ease-standard),
    color var(--motion-fast) var(--ease-standard), border-color var(--motion-fast) var(--ease-standard);
}
.platform-btn:hover{ background: var(--text-primary); color: var(--bg); border-color: var(--text-primary); }
.platform-btn--primary{ border-color: var(--text-primary); }

/* ============================================================
   SELECTED WORKS — role / visual proof (distinct purpose from Music)
============================================================= */
/* Wider grid gap than Music's internal rhythm (Patch 02 §09) — Works
   needed its own density, not Music's leftover spacing, so it doesn't
   read as an extension of the player list above it. */
.works-grid{ display:grid; grid-template-columns: repeat(3, 1fr); gap: clamp(20px, 2.6vw, 36px); }
/* Wrapper — 텍스트 정보 컨테이너일 뿐, 자체 클릭 영역이 아니다 (사용자 피드백:
   링크 영역을 앨범 이미지로만 한정, 텍스트는 비클릭). Video Card와 동일 패턴. */
.work-card{ display: block; width: 100%; }
/* Trigger — 앨범 이미지 영역만 실제 링크 */
.work-card__trigger{ display: block; color: inherit; text-decoration: none; }
.work-card__trigger .asset-slot{ aspect-ratio: 1/1; margin-bottom: 0; border: 0; overflow: hidden; }
/* Premium Release Index spacing rhythm (Patch 20260926_02 §03-2) —
   compact image → meta → title → description, no large block margins. */
.work-card__info{ padding-top: calc(var(--space-sm) / 2); }
.work-card__meta{
  font-family: var(--font-body); font-size: var(--scale-small); line-height: 1.4;
  color: var(--text-secondary); margin: 0;
}
.work-card__title{
  font-family: var(--font-display); font-size: var(--scale-h3); font-weight: 500;
  line-height: 1.2; color: var(--text-primary);
  margin: 2px 0 0;
  transition: color var(--motion-fast) var(--ease-standard);
}
.work-card__role{
  font-family: var(--font-body); font-size: var(--scale-small); line-height: 1.6;
  color: var(--text-secondary); margin: 4px 0 0;
}

/* Premium Release Index hover (Patch §03-3) — image scale + title accent
   only, triggered by hovering/focusing the image link itself (텍스트는
   비클릭이므로 자체 hover 상태를 갖지 않는다 — 형제 결합자로 제목에만 반영).
   No border highlight / outline / overlay on the Works image. */
@media (hover: hover){
  .work-card__trigger:hover .asset-slot__img{ transform: scale(1.04); }
  .work-card__trigger:hover ~ .work-card__info .work-card__title{ color: var(--accent); }
}
.work-card__trigger:focus-visible{ outline: 2px solid var(--accent); outline-offset: 4px; }
.work-card__trigger:focus-visible .asset-slot__img{ transform: scale(1.04); }
.work-card__trigger:focus-visible ~ .work-card__info .work-card__title{ color: var(--accent); }

/* ============================================================
   CAREER — Wide Performance Slider (top) + Career list (below).
   No text-over-image overlay (STEP 06 §12-13): brightness varies per
   photo, Korean event names can run long, and overlay text stability
   on mobile isn't reliable — so image and text stay fully separate.
============================================================= */
.career-slider{
  position: relative;
  /* More room below the slider than the shared --space-lg default
     (Patch 02 §10) — Career text needs to read as breathing room after
     the visual peak, not a caption stacked directly under the photo. */
  margin-bottom: clamp(40px, 5vw, 64px);
  outline: none;
  /* Clip mask lives on this static wrapper, not on the element that
     gets transformed (see .career-slider__track below). Overflow and
     transform on the SAME element move the clip window together with
     the content, so slides 2/3 never entered the visible frame —
     that was the root cause of the blank slides bug. */
  overflow: hidden;
  /* Subtle lift so the performance photo reads as the section's visual
     anchor against the elevated background, not flush with it (Patch 02
     §10 — Slider visual prominence). Shadow only, no border/glow/scale. */
  box-shadow: 0 32px 72px rgba(37, 39, 42, 0.16);
}
.career-slider[hidden]{ display:none; }
.career-slider__track{
  display:flex;
  transition: transform var(--motion-standard) var(--ease-standard);
}
.career-slider__slide{ flex: 0 0 100%; }
.career-slider__slide .asset-slot{ aspect-ratio: 16/9; }
/* Premium Media Slider interaction (Patch §08-3) — Desktop/Mobile 모두
   navigation은 Autoplay/Swipe/Keyboard/Indicator로만 이루어진다.
   Prev/Next 버튼은 접근성을 위해 DOM에 남기되 시각적으로 숨긴다. */
.career-slider__nav{ display: none; }

/* Bottom-center line indicators (Patch §08-2) — Premium과 동일한
   indicator language. 버튼은 script.js가 slide 수만큼 생성한다. */
.career-slider__indicators{
  position: absolute;
  bottom: var(--space-md);
  left: 50%;
  translate: -50% 0;

  display: flex;
  gap: 8px;
  z-index: 2;
}
.career-slider__indicators button{
  width: 20px;
  height: 2px;
  border: 0;
  background: rgba(245, 245, 244, 0.4);
  padding: 0;
  cursor: pointer;
}
.career-slider__indicators button[aria-current="true"]{
  background: var(--accent);
}
.career-slider__indicators button:focus-visible{
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.career-slider__indicators[hidden]{ display: none; }

.career-list{ display:flex; flex-direction:column; }
.career-list li{
  display:grid; grid-template-columns: 100px 1fr;
  gap: 24px; padding: 16px 0; border-bottom: 1px solid var(--border-soft);
}
.career-year{ font-family: var(--font-display); color: var(--text-tertiary); font-size: 14px; }
.career-desc{ font-size: 15px; color: var(--text-primary); }

/* ============================================================
   CREDITS — compact list
============================================================= */
.credits-list{ display:flex; flex-direction:column; }
.credits-list li{
  break-inside: avoid; padding: 12px 0; border-bottom: 1px solid var(--border-soft);
  font-size: 14px; display:flex; justify-content: space-between; gap: 12px;
}
.credit-title{ color: var(--text-primary); }
.credit-role{ color: var(--text-tertiary); text-align:right; }

.credits-list li.is-collapsed,
.career-list li.is-collapsed{ display:none; }
.credits-toggle{
  margin-top: 16px; background:none; border: 1px solid var(--border); color: var(--text-secondary);
  padding: 8px 16px; cursor:pointer; font-size: 13px;
}
.credits-toggle:hover, .credits-toggle:focus-visible{ color: var(--accent); border-color: var(--accent-line); }

/* ============================================================
   PROFESSIONAL PROOF — wraps Credits + Collaboration (Patch 01 §3)
   Sub-blocks are independently SHOW/HIDE; the whole section hides
   only when both sub-blocks are hidden.
============================================================= */
.proof-grid{ display:grid; grid-template-columns: 1fr 1fr; gap: var(--space-section); }
.proof-block__title{
  font-family: var(--font-display); font-weight: 500; font-size: 15px;
  color: var(--text-secondary); margin: 0 0 var(--space-md);
  text-transform: uppercase; letter-spacing: .04em;
}
.proof-block[hidden]{ display:none; }

/* ============================================================
   COLLABORATION
============================================================= */
.collab-list li{
  padding: 14px 0; border-bottom: 1px solid var(--border-soft);
  display:flex; gap: 20px; font-size: 14px;
}
.collab-year{ color: var(--text-tertiary); width: 60px; flex-shrink:0; }
.collab-desc{ color: var(--text-primary); }

/* ============================================================
   VIDEO
============================================================= */
/* Adaptive column state — NILO FIELD ships 2 video cards, so desktop and
   tablet use 2 balanced columns (no empty cell); mobile steps to 1 column
   at 768px (existing rule below). 16:9 thumbnails keep their ratio via
   .asset-slot; minmax(0,1fr) keeps cards from growing past the grid. */
.video-grid{ display:grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(16px, 2vw, 28px); }
/* Wrapper — 정보 표시 컨테이너일 뿐, 자체 클릭 영역이 아니다 (Patch 20260926_02 §04/§07-2) */
.video-card{ display: block; width: 100%; cursor: default; }
/* Trigger — 썸네일만 클릭 가능한 Modal 진입점 */
.video-card__trigger{
  display: block; width: 100%; padding: 0; border: 0; background: none;
  color: inherit; cursor: pointer; text-align: left;
}
.video-card__trigger .asset-slot{ aspect-ratio: 16/9; position: relative; border: 0; overflow: hidden; }

/* Premium-aligned play control (Patch §09-2, selector migrated to
   .video-card__trigger in Patch 20260926_02 §07-1) — 48px circle, CSS
   triangle child element on every viewport (Desktop/Mobile 동일 크기,
   §07 Important — Mobile에서 별도로 축소하지 않는다). */
.video-card__trigger .asset-slot::after{
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;

  width: 48px;
  height: 48px;
  border-radius: 50%;

  background: rgba(10, 11, 13, 0.55);
  box-shadow: inset 0 0 0 1.5px rgba(245, 245, 244, 0.9);

  transform: translate(-50%, -50%);
  transition:
    background var(--motion-fast) var(--ease-standard),
    transform var(--motion-fast) var(--ease-standard),
    box-shadow var(--motion-fast) var(--ease-standard);
}
.video-card__trigger .asset-slot::before{
  content: "";
  position: absolute;
  z-index: 2;
  top: 50%;
  left: 50%;

  width: 0;
  height: 0;
  border-style: solid;
  border-width: 7px 0 7px 11px;
  border-color: transparent transparent transparent var(--text-primary);

  transform: translate(calc(-50% + 2px), -50%);
  pointer-events: none;
  transition: border-color var(--motion-fast) var(--ease-standard);
}
@media (hover: hover){
  .video-card__trigger:hover .asset-slot::after{
    background: var(--accent);
    box-shadow: inset 0 0 0 1.5px var(--accent);
    transform: translate(-50%, -50%) scale(1.04);
  }
  .video-card__trigger:hover .asset-slot::before{ border-left-color: var(--bg); }
}
.video-card__trigger:focus-visible .asset-slot::after{
  background: var(--accent);
  box-shadow: inset 0 0 0 1.5px var(--accent);
  transform: translate(-50%, -50%) scale(1.04);
}
.video-card__trigger:focus-visible .asset-slot::before{ border-left-color: var(--bg); }
.video-card__trigger:focus-visible{ outline: 2px solid var(--accent); outline-offset: 4px; }
/* Mobile touch feedback (Patch §07-1) — :active mirrors the hover/focus
   accent state since (hover: hover) doesn't fire on touch devices. */
.video-card__trigger:active .asset-slot::after{
  background: var(--accent);
  box-shadow: inset 0 0 0 1.5px var(--accent);
  transform: translate(-50%, -50%) scale(1.04);
}
.video-card__trigger:active .asset-slot::before{ border-left-color: var(--bg); }

/* Info block — text-only, no click target (Patch §04/§06) */
.video-card__info{ padding-top: 8px; }
.video-card__title{
  font-family: var(--font-display); font-size: 1rem; font-weight: 500;
  line-height: 1.3; color: var(--text-primary); margin: 0;
}
.video-card__type{
  font-family: var(--font-body); font-size: var(--scale-small); line-height: 1.3;
  color: var(--text-secondary); margin: 2px 0 0;
}

/* ============================================================
   MEDIA MODAL (§22)
============================================================= */
.media-modal{ position: fixed; inset: 0; z-index: 300; display:flex; align-items:center; justify-content:center; padding: var(--edge); }
.media-modal[hidden]{ display: none; }
.media-modal__backdrop{ position:absolute; inset:0; background: rgba(0,0,0,0.7); backdrop-filter: blur(4px); }
.media-modal__panel{
  position: relative; z-index: 1; width: min(92vw, 1080px);
  background: var(--bg-elevated); border: 1px solid var(--border); padding: var(--space-md);
}
.media-modal__close{
  position:absolute; top: 12px; right: 12px; background:none; border:none; color: var(--text-secondary);
  font-size: 16px; cursor:pointer; padding: 6px; z-index: 2;
}
.media-modal__close:hover, .media-modal__close:focus-visible{ color: var(--accent); }
.media-modal__frame{
  aspect-ratio: 16/9; margin-bottom: 16px; background: var(--bg);
}
.media-modal__frame iframe{ width:100%; height:100%; display:block; }
.media-modal__title{ font-size: 15px; color: var(--text-primary); margin: 0 0 4px; }
.media-modal__type{ font-size: 12px; color: var(--text-tertiary); margin:0; }

/* ============================================================
   PRESS
============================================================= */
.press-disclaimer{ font-size:12px; color: var(--text-tertiary); margin: -12px 0 24px; }
/* Patch 03 §05 — Press outer/section-inner restored to the common
   site grid (same left/right edge as Video and Contact). Quiet/
   text-first density is kept by narrowing only the quote list's
   reading measure (--text-max, same token Bio uses), left-aligned
   under the title rather than centered as a standalone floating box. */
.press-list{ display:grid; grid-template-columns: 1fr; gap: var(--space-lg); max-width: var(--text-max); }
/* Press item = external article link (STEP 06 Production Content Patch 04
   §12-13). Editorial/Text-first, not a News Portal card — border-left
   accent + subtle color/underline on hover/focus is the only affordance. */
.press-card{
  display:block; border-left: 2px solid var(--accent-line); padding-left: 24px;
  text-decoration: none; color: inherit;
  transition: border-color var(--motion-fast) var(--ease-standard);
}
.press-card:hover, .press-card:focus-visible{ border-left-color: var(--accent); }
.press-card__title{
  font-family: var(--font-serif); font-size: 19px; line-height:1.65; margin:0 0 10px;
  color: var(--text-primary); text-underline-offset: 4px;
}
.press-card:hover .press-card__title,
.press-card:focus-visible .press-card__title{ text-decoration: underline; }
.press-card__meta{ font-size: 13px; color: var(--text-tertiary); display:flex; align-items:center; gap:6px; }
.press-card__arrow{ font-size:12px; opacity:.7; }

/* ============================================================
   CONTACT — Closing Composition (Patch 02 §15, rebalanced Patch 03 §06/07,
   image-crop sync added after feedback)
   Desktop: Contact Info 50% | Artist Image 50%, info column first in
   both DOM order and reading priority so it's read before the image.
   align-items: stretch keeps both outer columns on the same top/bottom
   grid boundary. Within that, the *visible* content on each side is
   additionally bottom-anchored: info's card+socials group via CSS
   (flex-end), and the image via script.js measuring that group's actual
   height and applying it to the image (see initContactVisualSync) — so
   the image is cropped to the same vertical span as the info content
   rather than stretching to fill the full column. CSS alone provides
   the JS-off fallback (image fills the full column height instead —
   no clipping/overflow either way, just not height-matched).
   Mobile (§07): visual order flips to Image → Info via `order` only —
   DOM/semantic order is untouched. Image is optional in markup —
   .contact-layout still works as a single column if .contact-visual
   isn't present.
============================================================= */
.contact-layout{
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(36px, 5vw, 64px);
  align-items: stretch;
}
.contact-info{ min-width: 0; display: flex; flex-direction: column; justify-content: flex-end; }
/* Single measurable group (card + social icons, normal --space-lg gap
   between them) that script.js reads the height of to size the image
   to match. justify-content:flex-end on the parent bottom-anchors this
   whole group; any leftover column height collects above it. */
.contact-info__content{ display: flex; flex-direction: column; gap: var(--space-lg); }
/* Contact fields stack in a single column inside the 50% info column
   (the original 3-up grid assumed the full section width) so
   Booking/Management stay readable instead of being squeezed
   into narrow slivers. Booking-only case (.contact-panel--compact)
   already renders as one column and is unaffected. */
.contact-info .contact-panel{ grid-template-columns: 1fr; gap: var(--space-md); margin-bottom: 0; }
.contact-visual{ min-width: 0; display: flex; align-items: flex-end; }
/* height:100% is the JS-off / pre-hydration fallback (fills the full
   stretched column, matching the outer grid boundary). Once
   initContactVisualSync measures .contact-info__content, it sets an
   inline height on this element that overrides the 100% and matches
   the info content's actual height — align-items:flex-end on the
   parent then bottom-anchors the now-shorter image so both the info
   group and the image share the same top and bottom line. */
.contact-visual .asset-slot{ height: 100%; max-height: 560px; border: none; background: transparent; }
@media (max-width: 768px){
  .contact-layout{ grid-template-columns: 1fr; gap: var(--space-lg); }
  .contact-visual{ order: 1; }
  .contact-info{ order: 2; }
  /* Single-column stack has no row to stretch/match against, so fall
     back to the inline aspect-ratio (4/5) for sizing regardless of any
     JS-applied inline height — avoids a 0-height collapse and keeps
     mobile unaffected by the desktop-only height sync. */
  .contact-visual .asset-slot{ height: auto !important; max-height: 360px; }
}

/* Contact intro copy (Patch 06 §01) — now lives inside .contact-panel
   as its first row so intro + Booking + Management read as one
   merged section; divider line separates it from the contact blocks.
   No max-width clamp — lets it run on one line at the column widths
   this section actually uses, wrapping only if the viewport is too
   narrow to fit it (never forced nowrap, to avoid overflow). */
.contact-intro{
  font-size: 14px; color: var(--text-secondary); line-height: 1.5;
}
.contact-panel .contact-intro{
  border-bottom: 1px solid var(--border);
  padding-bottom: var(--space-sm);
  /* Grid `gap` on .contact-panel already adds var(--space-md) after this
     row; without this, the divider sits 12px below the text but 24px
     above Booking — off-center and out of rhythm with the rest of the
     panel (Booking↔Management also uses --space-md). Pull the next
     row in by the difference so the divider sits symmetrically
     (--space-sm on both sides), matching the panel's internal ratio. */
  margin-bottom: calc(var(--space-sm) - var(--space-md));
}

.contact-panel{
  display:grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-md);
  padding: var(--space-lg); border: 1px solid var(--border); background: var(--bg-elevated);
  margin-bottom: var(--space-lg);
}
/* Booking-only (Missing Data case) — single block shouldn't stretch
   across a 3-column grid meant for up to three contact methods. */
.contact-panel--compact{ grid-template-columns: minmax(0, 360px); }
.contact-block{ display:flex; flex-direction:column; align-items:flex-start; gap: 6px; }
.contact-block__label{ font-size: 12px; color: var(--text-tertiary); text-transform:uppercase; letter-spacing:.05em; }
.contact-block__value{ font-size: 15px; overflow-wrap: anywhere; }
a.contact-block__value:hover{ color: var(--accent); }

/* Primary contact (Booking) — the one CTA priority this section
   should make unmistakable at a glance (STEP 05 §16). */
.contact-block--primary .contact-block__label{ color: var(--accent); }
.contact-block--primary .contact-block__value{
  font-family: var(--font-display); font-weight: 500; font-size: 18px;
}
/* Contact channel icons (STEP 06 §16) — original line-art SVGs using
   currentColor, never the platform's own brand color. */
.social-links{ display:flex; flex-wrap: wrap; gap: 14px; }
.social-links[hidden]{ display:none; }
.social-icon{
  display:flex; align-items:center; justify-content:center;
  width: 40px; height: 40px; border: 1px solid var(--border);
  color: var(--text-secondary);
  transition: color var(--motion-fast) var(--ease-standard), border-color var(--motion-fast) var(--ease-standard);
}
.social-icon svg{ width: 18px; height: 18px; }
.social-icon:hover{ color: var(--accent); border-color: var(--accent-line); }

/* ============================================================
   FOOTER
============================================================= */
.site-footer{ border-top: 1px solid var(--border); padding: 32px 0; color: var(--text-secondary); font-size: 12px; }
.footer-inner{ display:flex; flex-wrap: wrap; justify-content:space-between; align-items:baseline; gap: 8px; }
.footer-copyright,
.footer-signature{
  margin: 0; font-family: var(--font-body); font-size: 12px; font-weight: 400;
  line-height: 1.4; color: var(--text-secondary);
}
.footer-signature{ text-align: right; }
@media (max-width: 600px){
  .footer-inner{ align-items: flex-start; }
  .footer-signature{ text-align: left; }
}

/* ============================================================
   RESPONSIVE — 1440 / 1280 / 1024 / 992 / 834 / 768 / 480
   Patch 01 §5 재검토 결과:
   Hero 2열 유지 구간을 992→834까지 확장. 834(iPad 계열 portrait)에서도
   Artist Name/Positioning/CTA가 한 줄 유지에 문제 없고 Page Fold 안에
   Listen CTA까지 들어오는 걸 확인. 768 이하(폰 폭)에서만 1열로 전환.
============================================================= */
@media (max-width: 992px){
  .works-grid{ grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 834px){
  .proof-grid{ grid-template-columns: 1fr; gap: var(--space-lg); }
}

@media (max-width: 768px){
  .main-nav{ display:none; }
  .nav-toggle{ display:block; }
  .site-header.is-nav-open .main-nav{
    display:flex; position:absolute; top:100%; left:0; right:0;
    flex-direction:column; background: var(--bg); border-bottom: 1px solid var(--border);
    padding: var(--space-md) var(--edge); gap: 18px;
  }

  /* Hero collapses to 1 column here, not at 992 (Patch 01 §5).
     Portrait renders first (source order) so it's the first thing in
     the mobile viewport, not text-first (Final Cleanup §07). Sized to
     read as a real hero visual, not a small thumbnail. */
  .hero-inner{ grid-template-columns: 1fr; }
  .hero-visual{ display:flex; justify-content:center; width: 100%; }
  .hero-visual .asset-slot{ width: 100%; max-width: none; }

  /* Mobile Hero copy width (Patch §06-6/§12) — text reads across the
     full section content width, not a narrow 320~380px column. */
  .hero-copy{ width: 100%; max-width: none; }
  .hero-position{ width: 100%; max-width: none; }
  .hero-cta{ width: 100%; }

  /* Fixed breakpoint typography — Mobile (Patch 20260926_02 §10-3) */
  .hero-copy .eyebrow{ font-size: 0.875rem; }
  .hero-name{ font-size: 3rem; }
  .hero-position{ font-size: 1rem; }

  /* Mobile profile flow: Snapshot section hidden, compact meta line
     shown inside Hero instead (Patch 01 §6 — Option B) */
  .snapshot{ display: none; }
  .hero-meta-mobile{ display: block; }

  .video-grid{ grid-template-columns: 1fr; }

  /* Selected Works on mobile — 1 column, large image, not a dense
     thumbnail grid (Final Cleanup §11). */
  .works-grid{ grid-template-columns: 1fr; }

  /* Player C+ on mobile — Artwork → Title/Meta → Embed → Platform,
     vertical stack (Final Cleanup §10). Artwork stays a real visual
     anchor for the section, not a small icon-sized thumbnail. */
  .player{
    flex-direction: column; align-items: stretch; gap: 16px;
    width: 100%; min-width: 0; overflow: hidden;
    justify-content: flex-start;
    /* Tighter horizontal padding than the desktop card so the Spotify
       embed gets closer to its own comfortable minimum render width
       (~300px) instead of being squeezed by a 40px card gutter. */
    padding: var(--space-md) 20px;
  }
  .player-artwork{ flex: 0 0 auto; width: 100%; }
  .player-artwork .asset-slot{ width: 100%; max-width: 320px; margin: 0 auto; }
  .player-info{ text-align: center; }
  .player-embed{ flex: none; width: 100%; max-width: 100%; min-width: 0; }
  .music-embed__frame{ width: 100%; max-width: 100%; min-width: 0; }
  /* Embed → Spotify CTA gap eased to ~12px (was 8px — read as too tight
     in practice); Artwork/Info keep the full 16px breathing room. */
  .player-platforms{ margin-left: 0; margin-top: -4px; justify-content: center; width: 100%; }

  /* Primary track (Soft Circuit) — Embed is the sole mobile listen surface,
     the external Spotify CTA row is hidden here (STEP 06 Production
     Content Patch 04 §06). Desktop keeps both Embed and CTA. */
  .player:not(.player--secondary) .player-platforms{ display: none; }

  /* Secondary tracks (Glass Hours / Low Relay) — Desktop shows the full
     Player (Artwork + Embed + CTA, identical grammar to the primary track, §04).
     Mobile collapses the SAME DOM to a compact listen-link row: Artwork
     and Embed are hidden, only Title/Meta + Spotify CTA remain visible
     (Patch 04 §06 — no separate mobile markup, no duplicate DOM). */
  .player--secondary{
    flex-direction: row; align-items: center; justify-content: space-between;
    gap: 16px; width: 100%; min-width: 0; overflow: visible;
    border: none; border-bottom: 1px solid var(--border-soft);
    background: transparent; padding: 14px 4px;
  }
  .player--secondary .player-artwork,
  .player--secondary .player-embed{ display: none; }
  .player--secondary .player-info{ text-align: left; flex: 1 1 auto; min-width: 0; }
  .player--secondary .player-platforms{
    display: flex; margin: 0; width: auto; justify-content: flex-end; flex-shrink: 0;
  }

  /* Mobile motion reduction (STEP 05 §20) — shorter travel distance,
     standard timing instead of the longer editorial duration */
  .reveal{
    transform: translateY(10px);
    transition: opacity var(--motion-standard) var(--ease-standard),
                transform var(--motion-standard) var(--ease-standard);
  }

  .contact-panel{ grid-template-columns: 1fr; }

  /* Video Modal on mobile — never overflow the viewport (Final Cleanup §14) */
  .media-modal{ padding: var(--edge); }
  .media-modal__panel{ width: 94vw; }

  /* Contact icons — 44px minimum touch target (Final Cleanup §16) */
  .social-icon{ width: 44px; height: 44px; }

  /* Footer layout comes from the shared Premium-aligned .footer-inner
     rule + the 600px override below (Patch 20260926_02 §09-3) — no
     separate mobile-only column stack here. */
}

@media (max-width: 480px){
  .career-list li{ grid-template-columns: 72px 1fr; gap: 14px; }
  .hero-cta .btn{ flex: 1 1 auto; }
}

/* Fixed breakpoint typography — 390px 이하 (Patch 20260926_02 §10-3) */
@media (max-width: 390px){
  .hero-name{ font-size: 2.75rem; }
}


/* ============================================================
   CLIENT VISUAL CONFIGURATION — NILO FIELD (ARTIST_BASE · LIGHT)
   Appended override layer. Master selectors / DOM / interaction are
   untouched; only colour roles and image framing are adjusted.

   A) Text-role accent remap — --accent (#A7ADB3 Neutral Accent) stays
      on decorative lines / fills; where it was used as TEXT colour or
      as a FOCUS ring on a light surface it is mapped to the Secondary
      Text token so those states remain legible.
   B) Overlay-on-image states — play disc / slider indicators sit on
      photographs, so they are pinned to explicit light-on-dark values
      instead of page-theme tokens.
   C) Image framing — Package assets keep their original files and
      pixel sizes; Master slot ratios are kept, object-position only.
============================================================= */

/* A) text / focus roles */
.main-nav a:hover, .main-nav a:focus-visible{ color: var(--text-secondary); }
.btn--primary:hover{ background: var(--text-secondary); color: var(--bg); }
.btn:focus-visible{ outline-color: var(--text-secondary); }
.hero-copy .eyebrow{ color: var(--text-secondary); }
.bio-toggle:hover, .bio-toggle:focus-visible,
.credits-toggle:hover, .credits-toggle:focus-visible,
.social-icon:hover{ color: var(--text-secondary); border-color: var(--text-secondary); }
.media-modal__close:hover, .media-modal__close:focus-visible{ color: var(--text-primary); }
.work-card__trigger:focus-visible{ outline-color: var(--text-secondary); }
@media (hover: hover){
  .work-card__trigger:hover ~ .work-card__info .work-card__title{ color: var(--text-secondary); }
}
.work-card__trigger:focus-visible ~ .work-card__info .work-card__title{ color: var(--text-secondary); }
a.contact-block__value:hover{ color: var(--text-secondary); }
.video-card__trigger:focus-visible{ outline-color: var(--text-secondary); }

/* B) overlay-on-image */
.video-card__trigger .asset-slot::before{ border-left-color: #F2F1ED; }
@media (hover: hover){
  .video-card__trigger:hover .asset-slot::before{ border-left-color: var(--text-primary); }
}
.video-card__trigger:focus-visible .asset-slot::before,
.video-card__trigger:active .asset-slot::before{ border-left-color: var(--text-primary); }
.career-slider__indicators button[aria-current="true"]{ background: #F2F1ED; }
/* indicators sit on photographs of any brightness — thin graphite halo keeps them readable on light slides */
.career-slider__indicators button{ box-shadow: 0 0 0 0.5px rgba(37, 39, 42, 0.35), 0 1px 3px rgba(37, 39, 42, 0.45); }

/* C) image framing (Package asset → Master slot). Hero source is natively 4:5
      (no override needed); Bio 3:2 keeps the figure inside the wide crop;
      Contact 3:2 only crops horizontally on mobile → anchor to the right
      where the figure sits. */
#bioVisual .asset-slot__img{ object-position: center 52%; }
#contactVisualSlot .asset-slot__img{ object-position: 100% 50%; }

/* D) same-page anchor target — focused programmatically by the nav helper
      (script.js initAnchorAlignment); no visible ring on the section box */
main > section[tabindex="-1"]:focus{ outline: none; }
