/* ============================================================================
   josephbihag.com
   Tokens inherited from the Almost Impossible design system
   (impossible-project/src/design-tokens.css), flattened from HSL triplets to
   hex because there is no Tailwind here to compose them.

   Shape rule (one system, applied everywhere): containers, cards and images are
   SHARP (radius 0). Only interactive pills (filter chips, buttons) are fully
   rounded. Nothing in between.
   ============================================================================ */

:root{
  /* surfaces */
  --void:#000000;            /* page */
  --carbon:#141414;          /* card */
  --smoke:#1c1c1c;           /* elevated / hover */
  --ash:#262626;             /* hairline */
  --footer:#080808;

  /* text: measured in scripts/contrast.py, all AA on --void */
  --text:#fafafa;            /* 20.12:1 */
  --muted:#a1a1a1;           /*  8.13:1 */
  --accent:#e57200;          /*  6.74:1  PANTONE 152 C */
  --accent-hot:#ff6500;      /*  7.11:1  hover only */

  /* #666 is 3.66:1 and fails AA, so it is a LINE colour, never a text colour */
  --line:#262626;
  --line-soft:rgba(250,250,250,.09);
  --accent-line:rgba(229,114,0,.34);

  --display:"Klavika","Klavika Fallback",system-ui,sans-serif;
  --editorial:"Playfair Display",Georgia,serif;
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,monospace;

  --pill:999px;
  --ease:cubic-bezier(.16,1,.3,1);
  --pad:clamp(20px,4.5vw,64px);
  --nav-h:64px;
  --maxw:1400px;
}

/* ---------- fonts: all self-hosted, zero external requests ---------------- */
@font-face{font-family:"Klavika";src:url(fonts/klavika-light.woff2) format("woff2");font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:"Klavika";src:url(fonts/klavika-regular.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Klavika";src:url(fonts/klavika-regular-italic.woff2) format("woff2");font-weight:400;font-style:italic;font-display:swap}
@font-face{font-family:"Klavika";src:url(fonts/klavika-medium.woff2) format("woff2");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:"Klavika";src:url(fonts/klavika-bold.woff2) format("woff2");font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:"Playfair Display";src:url(fonts/playfairdisplay-400.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Playfair Display";src:url(fonts/playfairdisplay-400-italic.woff2) format("woff2");font-weight:400;font-style:italic;font-display:swap}
@font-face{font-family:"Playfair Display";src:url(fonts/playfairdisplay-600.woff2) format("woff2");font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:"JetBrains Mono";src:url(fonts/jetbrainsmono-400.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"JetBrains Mono";src:url(fonts/jetbrainsmono-500.woff2) format("woff2");font-weight:500;font-style:normal;font-display:swap}

/* ---------- base ---------------------------------------------------------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%; scroll-behavior:smooth}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  margin:0; background:var(--void); color:var(--text);
  font-family:var(--display); font-size:16px; line-height:1.6; font-weight:400;
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
  font-feature-settings:"kern" 1; overflow-x:hidden;
}
img{max-width:100%; height:auto; display:block}
a{color:inherit; text-decoration:none}
h1,h2,h3,h4{margin:0; font-weight:700; letter-spacing:-.03em; line-height:1.02; text-wrap:balance}
p{margin:0}
::selection{background:var(--accent); color:#000}

/* Atmosphere. Pure black is a locked brand token, so depth comes from a warm
   bloom plus grain rather than from lifting the background off #000.
   Both are fixed and pointer-events:none so they never repaint on scroll. */
body::before{
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(64ch 46ch at 88% -6%, rgba(229,114,0,.13), transparent 60%),
    radial-gradient(46ch 38ch at 2% 8%, rgba(229,114,0,.05), transparent 62%);
}
body::after{
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none; opacity:.035;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}
.page{position:relative; z-index:1}
.wrap{max-width:var(--maxw); margin:0 auto; padding:0 var(--pad)}
.wrap-narrow{max-width:980px; margin:0 auto; padding:0 var(--pad)}

/* focus is visible on every interactive element, never removed */
a:focus-visible,button:focus-visible,summary:focus-visible,[tabindex]:focus-visible{
  outline:2px solid var(--accent); outline-offset:3px;
}
.skip{position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--accent); color:#000; padding:12px 20px; font-weight:500}
.skip:focus{left:0}

/* ---------- navigation: one line, 64px ------------------------------------ */
.nav{
  position:sticky; top:0; z-index:40; height:var(--nav-h);
  display:flex; align-items:center; gap:24px;
  background:rgba(0,0,0,.78); backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line);
}
.nav-in{display:flex; align-items:center; gap:clamp(14px,2.4vw,30px); width:100%;
  max-width:var(--maxw); margin:0 auto; padding:0 var(--pad)}
.nav-mark{font-family:var(--display); font-weight:700; font-size:.98rem;
  letter-spacing:-.02em; margin-right:auto; white-space:nowrap}
.nav-mark b{color:var(--accent); font-weight:700}
.nav a:not(.nav-mark){
  font-family:var(--mono); font-size:.7rem; letter-spacing:.13em; text-transform:uppercase;
  color:var(--muted); display:inline-flex; align-items:center; justify-content:center;
  height:var(--nav-h); min-width:44px; padding:0 4px;
  transition:color .2s var(--ease); white-space:nowrap;
}
.nav a:not(.nav-mark):hover,.nav a[aria-current="page"]{color:var(--text)}
.nav a[aria-current="page"]{box-shadow:inset 0 -2px 0 var(--accent)}
@media(max-width:600px){
  .nav a:not(.nav-mark){font-size:.62rem; letter-spacing:.08em}
  .nav-in{gap:13px}
}

/* ---------- section grammar ----------------------------------------------- */
.sec{padding:clamp(64px,9vw,132px) 0; border-top:1px solid var(--line)}
.sec-hd{margin-bottom:clamp(30px,4vw,52px)}
.sec-hd h2{font-size:clamp(2rem,5.2vw,3.6rem)}
.sec-hd p{color:var(--muted); margin-top:14px; max-width:62ch; font-size:1.02rem}
.lede{color:var(--muted); margin-top:20px; max-width:60ch; font-size:1.06rem; line-height:1.65}

/* ============================================================================
   HERO. Asymmetric split. The portrait is 2000x872 with the subject on the
   right and clean negative space on the left, so the composition is doing the
   work; the left edge is faded into the page rather than cropped square.
   ============================================================================ */
.hero{
  min-height:calc(100dvh - var(--nav-h));
  display:grid; align-items:center;
  grid-template-columns:1fr; gap:clamp(28px,4vw,56px);
  padding:clamp(32px,5vw,72px) 0 clamp(40px,6vw,80px);
}
@media(min-width:900px){ .hero{grid-template-columns:1.06fr .94fr} }

.hero h1{
  font-size:clamp(3.2rem,10.5vw,8.2rem); line-height:.86; letter-spacing:-.05em;
  margin:0 0 clamp(18px,2.4vw,26px); font-weight:700;
}
.hero h1 .given{display:block; color:var(--muted); font-size:.34em; letter-spacing:-.01em;
  line-height:1; margin-bottom:.5em; font-weight:500}
.hero h1 .known{display:block}
.hero h1 .known em{font-style:normal; color:var(--accent)}

/* the compressed ledger: this is the hero subtext and the hook in one line */
.hero-sub{
  font-family:var(--mono); font-size:clamp(.78rem,1.5vw,.94rem); line-height:1.85;
  color:var(--muted); letter-spacing:.02em; margin:0 0 clamp(24px,3vw,34px);
  max-width:34ch; font-variant-numeric:tabular-nums;
}
.hero-sub b{color:var(--text); font-weight:500}
.hero-sub .n{color:var(--accent); font-weight:500}

.hero-cta{display:flex; flex-wrap:wrap; gap:12px}
.btn{
  display:inline-flex; align-items:center; gap:10px; min-height:48px; padding:0 24px;
  border-radius:var(--pill); border:1px solid var(--line);
  font-family:var(--display); font-size:.95rem; font-weight:500; cursor:pointer;
  background:transparent; color:var(--text);
  transition:background .24s var(--ease), border-color .24s var(--ease),
             color .24s var(--ease), transform .12s var(--ease);
}
.btn:hover{background:var(--smoke); border-color:var(--accent-line)}
.btn:active{transform:scale(.96)}
.btn-primary{background:var(--accent); border-color:var(--accent); color:#000; font-weight:600}
.btn-primary:hover{background:var(--accent-hot); border-color:var(--accent-hot); color:#000}
.btn svg{width:17px; height:17px; flex:none}

.hero-portrait{position:relative; overflow:hidden}
.hero-portrait img{
  width:100%; aspect-ratio:4/3; object-fit:cover; object-position:72% 26%;
  filter:grayscale(1) contrast(1.08);
}
@media(min-width:900px){ .hero-portrait img{aspect-ratio:5/6; object-position:68% 24%} }
/* fade the photo's own grey backdrop into the page instead of cutting a hard box */
.hero-portrait::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(90deg,var(--void) 0%,rgba(0,0,0,.55) 22%,transparent 58%),
             linear-gradient(0deg,var(--void) 0%,transparent 26%);
}

/* ============================================================================
   THE LEDGER. The hook. His bio renders sixty awards as one run-on sentence;
   this is the same data as a scoreboard. Counts are real, from his own bio.
   ============================================================================ */
.ledger-top{display:flex; align-items:flex-end; gap:clamp(20px,4vw,60px);
  flex-wrap:wrap; margin-bottom:clamp(28px,4vw,46px)}
.ledger-total{font-size:clamp(4.4rem,13vw,10rem); line-height:.8; letter-spacing:-.055em;
  color:var(--accent); font-variant-numeric:tabular-nums; font-weight:700}
.ledger-top h2{font-size:clamp(1.5rem,3.4vw,2.4rem); padding-bottom:.4em}
.ledger-top p{font-family:var(--mono); font-size:.72rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted); padding-bottom:.9em; margin-left:auto}

.ledger{display:grid; grid-template-columns:1fr; gap:0}
@media(min-width:760px){.ledger{grid-template-columns:1fr 1fr; column-gap:clamp(32px,5vw,80px)}}
.lrow{
  display:flex; align-items:baseline; gap:18px; padding:15px 0;
  border-bottom:1px solid var(--line-soft);
}
.lrow .c{
  font-family:var(--display); font-weight:700; font-size:1.5rem; letter-spacing:-.03em;
  color:var(--accent); font-variant-numeric:tabular-nums; min-width:2.2ch; text-align:right;
}
.lrow .b{font-family:var(--mono); font-size:.76rem; letter-spacing:.12em;
  text-transform:uppercase; color:var(--text)}
.lrow .q{font-family:var(--mono); font-size:.66rem; letter-spacing:.06em;
  color:var(--accent); white-space:nowrap; padding-left:2px}
/* last row in each grid column keeps no trailing rule, so the ledger ends on
   content rather than on an orphaned line */
.lrow:last-child,.lrow:nth-last-child(2):nth-child(odd){border-bottom:0}

/* the six single-award bodies get marks, not another eleven ledger rows */
.singles{display:flex; flex-wrap:wrap; gap:9px; margin-top:clamp(26px,3.4vw,40px)}
.single{
  font-family:var(--mono); font-size:.68rem; letter-spacing:.11em; text-transform:uppercase;
  color:var(--muted); border:1px solid var(--line); border-radius:var(--pill);
  padding:9px 15px; display:inline-flex; align-items:center; gap:8px;
}
.single i{font-style:normal; color:var(--accent); font-variant-numeric:tabular-nums}

/* ============================================================================
   WORK GRID. The grid-breaking move: Cannes and Grand Prix winners span two
   columns and carry their hero image, everything else is a compact card. The
   asymmetry is generated from real award data, not chosen for looks.
   ============================================================================ */
.work-grid{display:grid; grid-template-columns:1fr; gap:2px; background:var(--line)}
@media(min-width:680px){.work-grid{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1080px){.work-grid{grid-template-columns:repeat(4,1fr)}}

.card{
  position:relative; display:flex; flex-direction:column; background:var(--void);
  padding:20px; min-height:158px; overflow:hidden; isolation:isolate;
  transition:background .3s var(--ease), box-shadow .3s var(--ease);
}
.card:hover{box-shadow:inset 0 2px 0 var(--accent)}
.card:hover{background:var(--carbon)}
.card-client{font-family:var(--mono); font-size:.64rem; letter-spacing:.15em;
  text-transform:uppercase; color:var(--muted); margin-bottom:10px;
  transition:color .3s var(--ease)}
.card:hover .card-client{color:var(--accent)}
.card-title{font-size:1.16rem; letter-spacing:-.025em; margin-bottom:auto; font-weight:700}
.card-foot{display:flex; align-items:center; gap:10px; margin-top:16px; flex-wrap:wrap}
.card-cat{font-family:var(--mono); font-size:.6rem; letter-spacing:.1em;
  text-transform:uppercase; color:var(--muted)}
.card-arrow{width:16px; height:16px; margin-left:auto; color:var(--muted); flex:none;
  transition:transform .3s var(--ease), color .3s var(--ease)}
.card:hover .card-arrow{transform:translate(3px,-3px); color:var(--accent)}

/* awarded work carries a mark; top-tier work also carries the image */
.mark{
  display:inline-flex; align-items:center; gap:6px; font-family:var(--mono);
  font-size:.6rem; letter-spacing:.1em; text-transform:uppercase; color:var(--accent);
  border:1px solid var(--accent-line); border-radius:var(--pill); padding:4px 9px;
  font-variant-numeric:tabular-nums;
}
.card--feature{grid-column:span 1; min-height:340px; padding:0}
@media(min-width:680px){.card--feature{grid-column:span 2}}
.card--feature .card-media{position:absolute; inset:0; z-index:-1}
.card--feature .card-media img{width:100%; height:100%; object-fit:cover;
  filter:grayscale(1) contrast(1.06) brightness(.58);
  transition:transform .7s var(--ease), filter .5s var(--ease)}
.card--feature:hover .card-media img{transform:scale(1.045);
  filter:grayscale(.2) contrast(1.06) brightness(.68)}
.card--feature .card-media::after{content:""; position:absolute; inset:0;
  background:linear-gradient(0deg,rgba(0,0,0,.92) 0%,rgba(0,0,0,.72) 22%,
             rgba(0,0,0,.2) 58%,rgba(0,0,0,.55) 100%)}
/* Content sits at the bottom, not the top. Several source frames carry their
   own baked-in headline across the middle of the image (the Coca-Cola and Kit
   Kat stills especially), and a title at the top ran straight through it. The
   bottom is also where the scrim is heaviest, so the text is legible without
   darkening the picture further. */
.card--feature .card-body{position:relative; display:flex; flex-direction:column;
  justify-content:flex-end; height:100%; padding:24px}
.card--feature .card-title{margin-bottom:0}
.card--feature .card-title{font-size:clamp(1.5rem,2.6vw,2.15rem)}

/* filter chips */
.filters{display:flex; flex-wrap:wrap; gap:8px; margin-bottom:clamp(26px,3.4vw,38px)}
.chip{
  font-family:var(--mono); font-size:.66rem; letter-spacing:.11em; text-transform:uppercase;
  color:var(--muted); background:transparent; border:1px solid var(--line);
  border-radius:var(--pill); padding:0 15px; min-height:38px; cursor:pointer;
  display:inline-flex; align-items:center; gap:7px;
  transition:color .2s var(--ease), border-color .2s var(--ease),
             background .2s var(--ease), transform .12s var(--ease);
}
.chip:hover{color:var(--text); border-color:var(--accent-line)}
.chip:active{transform:scale(.96)}
.chip[aria-pressed="true"]{background:var(--accent); border-color:var(--accent);
  color:#000; font-weight:500}
.chip .n{font-variant-numeric:tabular-nums; opacity:.62}

/* ============================================================================
   CASE STUDY ARTICLE
   ============================================================================ */
.cs-head{padding:clamp(44px,6vw,90px) 0 clamp(30px,4vw,50px)}
.cs-client{font-family:var(--mono); font-size:.72rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--accent); margin-bottom:18px}
.cs-head h1{font-size:clamp(2.4rem,7vw,5.4rem); letter-spacing:-.045em; line-height:.94}
.cs-meta{display:flex; flex-wrap:wrap; gap:10px; margin-top:26px}

.prose{max-width:68ch}
.prose p{font-size:clamp(1.02rem,1.5vw,1.16rem); line-height:1.72; color:var(--muted);
  margin:0 0 1.25em}
.prose p:last-child{margin-bottom:0}
.prose a{color:var(--text); box-shadow:inset 0 -1px 0 var(--accent-line);
  transition:box-shadow .2s var(--ease), color .2s var(--ease)}
.prose a:hover{color:var(--accent); box-shadow:inset 0 -1px 0 var(--accent)}
.prose h2{font-size:clamp(1.4rem,2.8vw,2rem); margin:1.6em 0 .6em}

.figure{margin:clamp(30px,4.5vw,64px) 0}
.figure img{width:100%}
.figure figcaption{font-family:var(--mono); font-size:.72rem; line-height:1.6;
  color:var(--muted); margin-top:12px; max-width:72ch}
.gallery{display:grid; gap:2px; margin:clamp(30px,4.5vw,64px) 0;
  grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
.embed{position:relative; aspect-ratio:16/9; margin:clamp(30px,4.5vw,64px) 0;
  background:var(--carbon)}
.embed iframe{position:absolute; inset:0; width:100%; height:100%; border:0}

/* recognition: awards and press features are different things, kept apart */
.recog{display:grid; grid-template-columns:1fr; gap:0; margin-top:10px}
@media(min-width:820px){.recog{grid-template-columns:1fr 1fr; column-gap:clamp(30px,5vw,70px)}}
.recog a,.recog span{display:flex; align-items:baseline; gap:14px; padding:14px 0;
  border-bottom:1px solid var(--line-soft); font-size:.98rem; color:var(--text);
  transition:color .2s var(--ease)}
.recog a:hover{color:var(--accent)}
.recog .verify{margin-left:auto; font-family:var(--mono); font-size:.62rem;
  letter-spacing:.1em; text-transform:uppercase; color:var(--muted); white-space:nowrap}
.recog a:hover .verify{color:var(--accent)}

/* ============================================================================
   LOGO GALLERY
   ============================================================================ */
.logo-grid{display:grid; gap:2px; background:var(--line);
  grid-template-columns:repeat(auto-fill,minmax(248px,1fr))}
.logo-cell{background:var(--void); padding:18px; display:flex; flex-direction:column;
  gap:16px; transition:background .3s var(--ease)}
.logo-cell:hover{background:var(--carbon)}
/* The source marks are full-colour on solid white, with no alpha channel, so
   there is no blend mode that lifts them onto black. Rather than knock the
   colour out, each is shown as a white specimen plate, which is how Logolounge
   and Graphis actually printed them. Uniform across the grid, so it reads as a
   component and not as a section that flipped to light mode. */
.plate{background:#fff; padding:22px; overflow:hidden}
.plate img{width:100%; aspect-ratio:1/1; object-fit:contain;
  transition:transform .45s var(--ease)}
.logo-cell:hover .plate img{transform:scale(1.045)}
.logo-name{font-size:1.02rem; font-weight:600; letter-spacing:-.015em; margin-bottom:8px}
.logo-note{font-family:var(--mono); font-size:.66rem; line-height:1.7; color:var(--muted); margin:0}
.logo-tags{display:flex; flex-wrap:wrap; gap:6px; margin-top:11px}
.logo-books{margin:11px 0 0; font-family:var(--mono); font-size:.62rem; line-height:1.8;
  color:var(--muted); display:flex; flex-wrap:wrap; gap:0 9px; align-items:baseline}
.logo-books span{letter-spacing:.13em; text-transform:uppercase; color:var(--accent);
  width:100%; font-size:.58rem}
.logo-books i{font-style:normal}
.logo-books i + i::before{content:"/"; color:var(--line); padding-right:9px}
.logo-link{margin-top:auto; padding-top:14px; display:inline-flex; align-items:center; gap:8px;
  font-family:var(--mono); font-size:.62rem; letter-spacing:.12em; text-transform:uppercase;
  color:var(--muted); min-height:44px; transition:color .2s var(--ease)}
.logo-link:hover{color:var(--accent)}
.logo-link .r-go{width:13px; height:13px}

/* ============================================================================
   BIO. The one place the page breathes: Playfair, single column, real measure.
   ============================================================================ */
.bio-prose{font-family:var(--editorial); font-size:clamp(1.14rem,1.9vw,1.42rem);
  max-width:58ch}
.bio-prose p{font-size:inherit; line-height:1.66; color:var(--text); margin:0 0 1.02em}
.bio-prose p:first-of-type::first-letter{
  font-family:var(--editorial); float:left; font-size:4.1em; line-height:.82;
  padding:.06em .1em 0 0; color:var(--accent); font-weight:600;
}
/* every paragraph stays at full contrast: eight muted paragraphs read as a
   wall, and the drop cap is already the entry point */

.quotes{display:grid; grid-template-columns:1fr; gap:2px; background:var(--line)}
@media(min-width:900px){.quotes{grid-template-columns:repeat(3,1fr)}}
.quote{background:var(--void); padding:clamp(24px,3vw,36px);
  display:flex; flex-direction:column; gap:18px}
.quote blockquote{margin:0; font-family:var(--editorial); font-size:1.16rem;
  line-height:1.5; color:var(--text)}
.quote figcaption{margin-top:auto; font-family:var(--mono); font-size:.66rem;
  line-height:1.75; letter-spacing:.1em; text-transform:uppercase; color:var(--muted)}
.quote figcaption b{display:block; color:var(--accent); font-weight:500}

/* ============================================================================
   LINK ROWS (the link-in-bio index). Signature orange wipe, inherited from
   braedenbihag.com so the two sites read as one family.
   ============================================================================ */
.rows{border-top:1px solid var(--line)}
.row{
  position:relative; display:flex; align-items:center; gap:16px; min-height:66px;
  padding:16px 18px; border-bottom:1px solid var(--line); overflow:hidden; isolation:isolate;
  transition:transform .12s var(--ease);
}
.row::before{content:""; position:absolute; inset:0; background:var(--accent); z-index:-1;
  transform:scaleX(0); transform-origin:left; transition:transform .44s var(--ease)}
.row:hover::before,.row:focus-visible::before{transform:scaleX(1)}
.row:focus-visible{outline:2px solid var(--accent); outline-offset:-2px}
.row:active{transform:scale(.994)}
.r-icon{width:19px; height:19px; flex:none; color:var(--muted); transition:color .3s var(--ease)}
.r-label{font-size:1.04rem; font-weight:500; transition:color .3s var(--ease)}
.r-val{margin-left:auto; font-family:var(--mono); font-size:.74rem; color:var(--muted);
  transition:color .3s var(--ease); white-space:nowrap; overflow:hidden;
  text-overflow:ellipsis; max-width:42vw}
.r-go{width:16px; height:16px; flex:none; color:var(--muted);
  transition:transform .3s var(--ease), color .3s var(--ease)}
.row:hover .r-icon,.row:hover .r-label,.row:hover .r-val,.row:hover .r-go{color:#000}
.row:hover .r-go{transform:translateX(3px)}
@media(max-width:560px){.r-val{display:none}}

/* ---------- footer -------------------------------------------------------- */
.foot{background:var(--footer); border-top:1px solid var(--line);
  padding:clamp(56px,7vw,96px) 0 48px; position:relative; z-index:1}
.foot-cta{font-size:clamp(1.9rem,5.6vw,3.4rem); letter-spacing:-.04em;
  max-width:16ch; margin:0 0 16px}
.foot-cta a{position:relative; display:inline-block; padding:6px 0; margin:-6px 0;
  transition:color .24s var(--ease)}
.foot-cta a::after{content:""; position:absolute; left:0; right:0; bottom:6px; height:2px;
  background:var(--accent-line); transition:background .24s var(--ease)}
.foot-cta a:hover{color:var(--accent)}
.foot-cta a:hover::after{background:var(--accent)}
.foot-sub{color:var(--muted); max-width:48ch; margin:0 0 36px}
.foot-bot{display:flex; justify-content:space-between; align-items:center; gap:18px;
  flex-wrap:wrap; font-family:var(--mono); font-size:.66rem; letter-spacing:.09em;
  color:var(--muted); border-top:1px solid var(--line); padding-top:26px}
.foot-bot nav{display:flex; gap:20px; flex-wrap:wrap}
.foot-bot a{display:inline-flex; align-items:center; justify-content:center;
  min-height:44px; min-width:44px; transition:color .2s var(--ease)}
.foot-bot a:hover{color:var(--accent)}

/* ---------- private tier banner (injected at the edge, never in static HTML) */
.private{display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  padding:13px var(--pad); background:rgba(229,114,0,.07);
  border-bottom:1px solid var(--accent-line); font-size:.88rem; color:var(--muted)}
.private b{font-family:var(--mono); font-size:.62rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--accent); border:1px solid var(--accent-line);
  border-radius:var(--pill); padding:4px 10px; font-weight:400}

/* ============================================================================
   MOTION. One orchestrated load, then quiet reveals. Everything is transform
   and opacity only. All of it collapses under reduced-motion.
   ============================================================================ */
.js .rv{opacity:0; transform:translateY(18px)}
.js .rv.in{opacity:1; transform:none;
  transition:opacity .7s var(--ease), transform .7s var(--ease); transition-delay:var(--d,0ms)}

/* hero name: masked line reveal, communicates the page arriving rather than fading */
.js .hero h1 .given,.js .hero h1 .known{overflow:hidden}
.js .hero h1 span > i{display:block; font-style:normal; transform:translateY(105%);
  transition:transform .9s var(--ease)}
.js .hero.in h1 span > i{transform:none}
.js .hero.in h1 .known > i{transition-delay:.08s}

@media(prefers-reduced-motion:reduce){
  .js .rv,.js .rv.in{opacity:1; transform:none; transition:none}
  .js .hero h1 span > i,.js .hero.in h1 span > i{transform:none; transition:none}
  *,*::before,*::after{animation-duration:.001ms !important; transition-duration:.001ms !important}
}

/* print: the archive should survive being printed, which juries still do */
@media print{
  body::before,body::after,.nav,.foot-bot{display:none}
  body{background:#fff; color:#000}
  .card,.logo-cell,.quote{background:#fff}
}

/* ---------- utilities the templates rely on ------------------------------- */
.sec-more{margin-top:clamp(28px,4vw,48px)}
.sec-recog{margin-top:clamp(40px,6vw,80px)}
.sec-hd-sub{margin-top:44px}
.empty{color:var(--muted); padding:48px 0}

/* ============================================================================
   POLISH
   ============================================================================ */

/* Photographs sit directly on #000 with no edge, so a dark frame reads as a
   crop rather than as an image. A pure-white hairline at low alpha defines the
   edge without tinting the picture. */
.figure img,.gallery img,.card--feature .card-media img{
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.08);
}
.plate{box-shadow:inset 0 0 0 1px rgba(0,0,0,.14)}

/* Press feedback on the whole card, matching the buttons and chips */
.card:active{transform:scale(.995)}
.card{transition:background .3s var(--ease), box-shadow .3s var(--ease),
      transform .12s var(--ease)}
/* Cards tile with a 2px gap, so an offset ring would sit on the neighbour.
   Drawn inside instead. */
#grid a.card:focus-visible,.work-grid a.card:focus-visible{outline-offset:-2px}

/* Ragged right on long prose reads better than the default greedy break */
.prose p,.bio-prose p,.lede,.sec-hd p{text-wrap:pretty}

/* Numbers that change on screen must not jitter as they count */
.ledger-total,.lrow .c,.single i{font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1}

/* ---------- admin form (behind Cloudflare Access, never public) ----------- */
.admin-notice{max-width:56ch; margin:0 0 20px; padding:12px 16px; border:1px solid var(--accent-line);
  color:var(--muted); font-family:var(--mono); font-size:.72rem; letter-spacing:.02em}
.admin-form{max-width:56ch}
.admin-row{border:1px solid var(--line); padding:18px 20px 20px; margin:0 0 14px;
  display:grid; gap:12px}
.admin-row legend{font-family:var(--mono); font-size:.64rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--accent); padding:0 6px}
.admin-row label{display:grid; gap:6px; font-family:var(--mono); font-size:.66rem;
  letter-spacing:.1em; text-transform:uppercase; color:var(--muted)}
.admin-row input{background:var(--carbon); border:1px solid var(--line); color:var(--text);
  font-family:var(--display); font-size:1rem; padding:11px 13px; min-height:44px}
.admin-row input:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
.admin-del{justify-self:start; min-height:44px; padding:0 16px; cursor:pointer;
  background:transparent; border:1px solid var(--line); border-radius:var(--pill);
  color:var(--muted); font-family:var(--mono); font-size:.64rem; letter-spacing:.12em;
  text-transform:uppercase}
.admin-del:hover{color:var(--accent); border-color:var(--accent-line)}
#admin-status{margin-top:18px; color:var(--muted); font-family:var(--mono); font-size:.76rem}

/* ---------- FAQ: native details, no JS ----------------------------------- */
.faq{border-top:1px solid var(--line); max-width:74ch}
.faq-item{border-bottom:1px solid var(--line)}
.faq-item summary{cursor:pointer; list-style:none; padding:20px 0; font-size:1.06rem;
  font-weight:500; display:flex; align-items:center; gap:16px; min-height:44px;
  transition:color .2s var(--ease)}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary::after{content:"+"; margin-left:auto; font-family:var(--mono);
  color:var(--accent); font-size:1.2rem; line-height:1}
.faq-item[open] summary::after{content:"\2013"}
.faq-item summary:hover{color:var(--accent)}
.faq-item p{color:var(--muted); margin:0 0 22px; max-width:66ch; line-height:1.7}
