/* ============================================================
   BRANDON — PORTFOLIO
   Type: UnifrakturCook (textura display) / Grenze / JetBrains Mono
   Ornament: Andalusi star-and-cross geometry, generated in main.js
   ============================================================ */

/* ---------- 0. FONTS (self-hosted — no external requests) ---------- */

/* ============================================================
   ►► TO CHANGE THE DISPLAY FACE, EDIT THE THREE VALUES MARKED
      "SWITCH HERE" IN THE :root BLOCK JUST BELOW. Nothing else.
      All six candidate faces are already loaded and licensed.
   ============================================================ */

/* The display face — real textura, drawn heavy enough to stay legible.
   SIL Open Font Licence: free for commercial use, no attribution needed. */
@font-face{font-family:"UnifrakturCook";src:url("../fonts/unifrakturcook-latin-700-normal.woff2") format("woff2");font-weight:700;font-style:normal;font-display:swap}

/* variable — the whole 100→900 range from one file */
@font-face{font-family:"Grenze Gotisch";src:url("../fonts/grenze-gotisch-latin-wght-normal.woff2") format("woff2-variations");font-weight:100 900;font-style:normal;font-display:swap}
@font-face{font-family:"Cormorant";src:url("../fonts/cormorant-latin-wght-normal.woff2") format("woff2-variations");font-weight:300 700;font-style:normal;font-display:swap}
@font-face{font-family:"Cormorant";src:url("../fonts/cormorant-latin-wght-italic.woff2") format("woff2-variations");font-weight:300 700;font-style:italic;font-display:swap}
/* single-weight alternates */
@font-face{font-family:"Cinzel";src:url("../fonts/cinzel-latin-400-normal.woff2") format("woff2");font-weight:400;font-display:swap}
@font-face{font-family:"Italiana";src:url("../fonts/italiana-latin-400-normal.woff2") format("woff2");font-weight:400;font-display:swap}
@font-face{font-family:"Marcellus";src:url("../fonts/marcellus-latin-400-normal.woff2") format("woff2");font-weight:400;font-display:swap}
@font-face{font-family:"Amiri";src:url("../fonts/amiri-latin-400-normal.woff2") format("woff2");font-weight:400;font-display:swap}

/* text + interface */
@font-face{font-family:"Grenze";src:url("../fonts/grenze-latin-300-normal.woff2") format("woff2");font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:"Grenze";src:url("../fonts/grenze-latin-300-italic.woff2") format("woff2");font-weight:300;font-style:italic;font-display:swap}
@font-face{font-family:"Grenze";src:url("../fonts/grenze-latin-400-normal.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Grenze";src:url("../fonts/grenze-latin-400-italic.woff2") format("woff2");font-weight:400;font-style:italic;font-display:swap}
@font-face{font-family:"Grenze";src:url("../fonts/grenze-latin-500-normal.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:"Inter";src:url("../fonts/inter-latin-300-normal.woff2") format("woff2");font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:"Inter";src:url("../fonts/inter-latin-400-normal.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Inter";src:url("../fonts/inter-latin-500-normal.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:"JetBrains Mono";src:url("../fonts/jetbrains-mono-latin-400-normal.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"JetBrains Mono";src:url("../fonts/jetbrains-mono-latin-500-normal.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap}

/* ---------- 1. TOKENS ---------- */
:root{
  --ink:#08080A;
  --ink-2:#101013;
  --ink-3:#191920;
  --vellum:#E9E7E0;
  --vellum-2:#DEDBD2;
  --vellum-3:#CFCBC0;
  /* accent is off by default. Set it to #F4685C (coral) or #FFC629 (yellow)
     to bring in the single-colour poster treatment from the reference board. */
  --accent:currentColor;
  --paper:#FFFFFF;

  /* semantic — flipped by [data-theme="dark"] */
  --bg:var(--vellum);
  --bg-2:var(--vellum-2);
  --fg:var(--ink);
  --fg-muted:#6C6960;
  --fg-faint:#A6A297;
  --line:rgba(8,8,10,.16);
  --line-soft:rgba(8,8,10,.08);
  --stroke:#08080A;

  /* ►► SWITCH HERE — display face. Currently UnifrakturCook Bold (textura).
     These are all bundled already if you want to change course later:
       "Grenze Gotisch" 300 / .015em     modern minimal blackletter
       "Grenze Gotisch" 600 / .008em     same face, heavier
       "Cormorant"      300 / -.012em    high contrast, finest detail
       "Cinzel"         400 / .035em     monumental Roman caps
       "Italiana"       400 / .025em     hairline, most ethereal
       "Marcellus"      400 / .018em     warm classical
       "Amiri"          400 / 0          Andalusi lineage                       */
  --f-display:       "UnifrakturCook", "Grenze Gotisch", "Times New Roman", serif;
  --display-weight:  700;
  --display-track:   .004em;
  --outline-w:       clamp(1.2px, .15vw, 2.6px);   /* stroke weight for outlined type */

  /* Display faces this fine don't survive small settings, so anything under
     ~28px is set in the sturdier sibling. Sub-heads, card titles, numerals. */
  --f-display-sm: "Grenze", "Times New Roman", serif;

  --f-serif:  "Grenze", "Times New Roman", serif;            /* editorial text */
  --f-mono:   "JetBrains Mono", ui-monospace, monospace;     /* labels, data */
  --f-body:   "Inter", -apple-system, system-ui, sans-serif; /* small UI text */

  --pad: clamp(20px, 4.2vw, 68px);
  --rule: 1px;

  --e-out: cubic-bezier(.16,1,.3,1);
  --e-io:  cubic-bezier(.65,.05,.36,1);
}

[data-theme="dark"]{
  --bg:var(--ink);
  --bg-2:var(--ink-2);
  --fg:var(--vellum);
  --fg-muted:#8E8A81;
  --fg-faint:#55524B;
  --line:rgba(233,231,224,.18);
  --line-soft:rgba(233,231,224,.08);
  --stroke:#E9E7E0;
}

/* ---------- 2. RESET ---------- */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{
  background:var(--bg);
  color:var(--fg);
  font-family:var(--f-body);
  font-size:16px;
  line-height:1.55;
  font-feature-settings:"kern" 1,"liga" 1;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
  transition:background .6s var(--e-io), color .6s var(--e-io);
}
img,svg,video{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0}
::selection{background:var(--fg);color:var(--bg)}

/* ---------- 3. TYPE PRIMITIVES ---------- */
.display{
  font-family:var(--f-display);
  font-weight:var(--display-weight);
  line-height:1.04;
  letter-spacing:var(--display-track);
  text-transform:none;
}
/* blackletter has no real italic — emphasis switches to the text sibling */
.display em{font-family:var(--f-serif);font-style:italic;font-weight:400;letter-spacing:-.01em}

.d1{font-size:clamp(2.9rem, 10.6vw, 11rem)}
.d2{font-size:clamp(2.3rem, 7.4vw, 7rem)}
.d3{font-size:clamp(2rem, 4.6vw, 4rem)}
.d4{font-size:clamp(1.5rem, 2.6vw, 2.3rem)}

.mono{
  font-family:var(--f-mono);
  font-size:.66rem;
  font-weight:400;
  letter-spacing:.22em;
  text-transform:uppercase;
  line-height:1.4;
}
.mono-sm{font-size:.6rem;letter-spacing:.26em}
.muted{color:var(--fg-muted)}
.faint{color:var(--fg-faint)}

.lede{
  font-family:var(--f-serif);
  font-size:clamp(1.35rem, 2.5vw, 2.2rem);
  line-height:1.32;
  font-weight:400;
  letter-spacing:-.01em;
  max-width:22ch;
}
.body-lg{font-family:var(--f-serif);font-size:clamp(1.06rem,1.25vw,1.24rem);line-height:1.68;color:var(--fg-muted);max-width:62ch}
.body-lg strong{color:var(--fg);font-weight:500}

/* ---------- 4. LAYOUT ---------- */
.wrap{width:100%;padding-inline:var(--pad)}
.section{position:relative;padding-block:clamp(70px,11vw,170px)}
.grid{display:grid;grid-template-columns:repeat(12,1fr);gap:clamp(16px,2vw,28px)}
.rule{height:var(--rule);background:var(--line);width:100%;border:0}

/* section header: "§ 02 / SELECTED WORK" + rule */
.sec-head{
  display:flex;align-items:baseline;gap:1.4rem;
  padding-bottom:1rem;margin-bottom:clamp(34px,5vw,72px);
  border-bottom:var(--rule) solid var(--line);
}
.sec-head .idx{color:var(--fg-faint)}
.sec-head .ttl{flex:1}
.sec-head .aside{color:var(--fg-faint);text-align:right}

/* ---------- 5. FIXED CHROME: grid, grain, cursor ---------- */
.overlay-grid{
  position:fixed;inset:0;z-index:2;pointer-events:none;
  display:grid;grid-template-columns:repeat(12,1fr);
  padding-inline:var(--pad);
}
.overlay-grid span{border-left:1px solid var(--line-soft)}
.overlay-grid span:last-child{border-right:1px solid var(--line-soft)}
@media(max-width:860px){.overlay-grid span:nth-child(n+7){display:none}
  .overlay-grid{grid-template-columns:repeat(6,1fr)}}

.grain{
  position:fixed;inset:-50%;z-index:3;pointer-events:none;opacity:.5;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='260'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.32'/%3E%3C/svg%3E");
  mix-blend-mode:multiply;
  animation:grainShift 6s steps(6) infinite;
}
[data-theme="dark"] .grain{mix-blend-mode:screen;opacity:.32}
@keyframes grainShift{
  0%{transform:translate(0,0)}20%{transform:translate(-4%,3%)}40%{transform:translate(3%,-5%)}
  60%{transform:translate(-3%,-3%)}80%{transform:translate(5%,4%)}100%{transform:translate(0,0)}
}

.cursor,.cursor-dot{
  position:fixed;top:0;left:0;z-index:9999;pointer-events:none;
  mix-blend-mode:difference;will-change:transform;
}
.cursor{
  width:34px;height:34px;margin:-17px 0 0 -17px;
  border:1px solid #fff;border-radius:50%;
  transition:width .35s var(--e-out),height .35s var(--e-out),margin .35s var(--e-out),opacity .3s;
}
.cursor-dot{width:3px;height:3px;margin:-1.5px 0 0 -1.5px;background:#fff;border-radius:50%}
.cursor.is-hover{width:76px;height:76px;margin:-38px 0 0 -38px}
.cursor .label{
  position:absolute;inset:0;display:grid;place-items:center;
  font-family:var(--f-mono);font-size:.5rem;letter-spacing:.16em;color:#fff;
  opacity:0;transition:opacity .25s;text-transform:uppercase;
}
.cursor.is-hover .label{opacity:1}
@media(hover:none),(max-width:860px){.cursor,.cursor-dot{display:none}}

/* scroll progress */
.progress{position:fixed;top:0;left:0;height:2px;width:100%;z-index:60;pointer-events:none}
.progress i{display:block;height:100%;width:0;background:var(--fg);transform-origin:left}

/* ---------- 6. PRELOADER ---------- */
.preload{
  position:fixed;inset:0;z-index:9000;background:var(--ink);color:var(--vellum);
  display:grid;place-items:center;
  animation:preFail .1s linear 3.4s forwards;
}
.preload.done{transform:translateY(-101%);transition:transform 1s var(--e-out)}
@keyframes preFail{to{transform:translateY(-101%)}}
.preload .pl-inner{text-align:center}
.preload .pl-rose{width:104px;height:104px;margin:0 auto 26px;opacity:.75}
.preload .pl-num{font-family:var(--f-mono);font-size:.7rem;letter-spacing:.3em}

/* ---------- 7. HEADER ---------- */
.hdr{
  position:fixed;top:0;left:0;right:0;z-index:50;
  display:flex;align-items:center;justify-content:space-between;
  padding:18px var(--pad);
  mix-blend-mode:difference;color:#fff;
}
.hdr a,.hdr span{color:#fff}
.hdr .mark{display:flex;align-items:center;gap:.7rem}
.hdr .mark .glyph{
  font-family:var(--f-display);font-size:1.35rem;line-height:1;
  border:1px solid rgba(255,255,255,.5);width:26px;height:26px;
  display:grid;place-items:center;padding-bottom:2px;
}
.hdr nav{display:flex;gap:1.8rem;align-items:center}
.hdr nav a{position:relative;padding-block:4px}
.hdr nav a::after{
  content:"";position:absolute;left:0;bottom:0;height:1px;width:100%;
  background:#fff;transform:scaleX(0);transform-origin:right;
  transition:transform .5s var(--e-out);
}
.hdr nav a:hover::after{transform:scaleX(1);transform-origin:left}
.status{display:flex;align-items:center;gap:.5rem}
.status .dot{width:5px;height:5px;border-radius:50%;background:#fff;animation:pulse 2.4s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.25}}
@media(max-width:720px){.hdr nav{display:none}}

/* ---------- 8. HERO ---------- */
.hero{
  position:relative;min-height:100svh;
  display:flex;flex-direction:column;justify-content:flex-end;
  padding:120px var(--pad) 0;
  overflow:hidden;
}
/* jali screen — a carved lattice behind the type, not a spinning disc */
.hero-lattice{
  position:absolute;inset:0;pointer-events:none;opacity:.34;color:var(--fg);
  /* dense at the top right, dissolving toward the type in the lower left —
     a screen the headline steps out from, not wallpaper */
  -webkit-mask-image:radial-gradient(ellipse 92% 88% at 78% 8%, #000 0%, rgba(0,0,0,.55) 42%, transparent 82%);
          mask-image:radial-gradient(ellipse 92% 88% at 78% 8%, #000 0%, rgba(0,0,0,.55) 42%, transparent 82%);
}
[data-theme="dark"] .hero-lattice{opacity:.4}
.lattice-band{
  position:absolute;inset:0;pointer-events:none;opacity:.16;color:var(--fg);
  -webkit-mask-image:linear-gradient(180deg,transparent,#000 45%,#000 55%,transparent);
          mask-image:linear-gradient(180deg,transparent,#000 45%,#000 55%,transparent);
}

.hero-meta{
  display:flex;justify-content:space-between;gap:1rem;
  padding-bottom:clamp(24px,5vw,60px);
  border-bottom:var(--rule) solid var(--line);
  margin-bottom:clamp(20px,3vw,34px);
  position:relative;z-index:2;
}
.hero-title{position:relative;z-index:2}
.hero-title .ln{display:block;overflow:hidden}
.hero-title .ln > span{display:block}
.hero-foot{
  position:relative;z-index:2;
  display:flex;justify-content:space-between;align-items:flex-end;gap:2rem;
  padding-block:clamp(26px,4vw,52px) clamp(20px,3vw,34px);
  flex-wrap:wrap;
}
.scroll-cue{display:flex;align-items:center;gap:.6rem;color:var(--fg-muted)}
.scroll-cue i{display:block;width:1px;height:34px;background:var(--line);position:relative;overflow:hidden}
.scroll-cue i::after{content:"";position:absolute;inset:0;background:var(--fg);animation:cue 2s var(--e-io) infinite}
@keyframes cue{0%{transform:translateY(-100%)}50%{transform:translateY(0)}100%{transform:translateY(100%)}}

/* ---------- 9. MARQUEE ---------- */
.marquee{
  border-block:var(--rule) solid var(--line);
  padding-block:14px;overflow:hidden;white-space:nowrap;
  display:flex;position:relative;z-index:2;
}
.marquee .track{display:flex;gap:2.6rem;padding-right:2.6rem;animation:slide 42s linear infinite;flex-shrink:0}
.marquee:hover .track{animation-play-state:paused}
.marquee .track span{display:flex;align-items:center;gap:2.6rem}
.marquee .track span::after{content:"✦";font-size:.6rem;opacity:.4}
@keyframes slide{to{transform:translateX(-100%)}}

/* ---------- 10. MANIFEST ---------- */
.manifest{position:relative}
.manifest .stmt{
  grid-column:2/12;
  font-family:var(--f-serif);
  font-size:clamp(1.5rem,3.5vw,3.15rem);
  line-height:1.22;letter-spacing:-.018em;font-weight:400;
}
.manifest .stmt em{font-style:italic}
.manifest .stmt .dim{color:var(--fg-faint)}
@media(max-width:860px){.manifest .stmt{grid-column:1/-1}}

/* ---------- 11. WORK INDEX ---------- */
.work-list{border-top:var(--rule) solid var(--line)}
.work-row{
  position:relative;display:block;
  border-bottom:var(--rule) solid var(--line);
  padding-block:clamp(22px,3.4vw,44px);
}
.work-row .inner{
  display:grid;grid-template-columns:auto 1fr auto auto;
  align-items:center;gap:clamp(14px,2.5vw,40px);
  transition:transform .8s var(--e-out);
}
.work-row:hover .inner{transform:translateX(clamp(8px,1.4vw,22px))}
.work-row .num{color:var(--fg-faint);align-self:flex-start;padding-top:.6em}
.work-row .name{
  font-family:var(--f-display);text-transform:none;
  font-size:clamp(1.55rem,4.6vw,4rem);line-height:1.06;letter-spacing:var(--display-track);
  font-weight:var(--display-weight);
}
.work-row .name{transition:letter-spacing .6s var(--e-out),opacity .4s}
.work-row:hover .name{letter-spacing:.028em}
.work-row .tags{color:var(--fg-muted);text-align:right;white-space:nowrap}
.work-row .arrow{
  width:34px;height:34px;flex:none;
  display:grid;place-items:center;border:1px solid var(--line);border-radius:50%;
  transition:background .5s var(--e-out),color .5s var(--e-out),transform .6s var(--e-out);
}
.work-row:hover .arrow{background:var(--fg);color:var(--bg);transform:rotate(45deg)}
.work-row .sub{
  grid-column:2/3;color:var(--fg-muted);margin-top:.9rem;
  font-family:var(--f-serif);font-size:1.02rem;line-height:1.6;max-width:48ch;
}
@media(max-width:860px){
  .work-row .inner{grid-template-columns:auto 1fr auto}
  .work-row .tags{display:none}
}

/* cursor-follow preview */
.peek{
  position:fixed;top:0;left:0;z-index:40;pointer-events:none;
  width:clamp(200px,20vw,300px);aspect-ratio:4/5;
  opacity:0;transform:translate(-50%,-50%) scale(.9);
  transition:opacity .45s var(--e-out),transform .6s var(--e-out);
  overflow:hidden;
}
.peek.on{opacity:1;transform:translate(-50%,-50%) scale(1)}
.peek .pk{position:absolute;inset:0;opacity:0;transition:opacity .35s}
.peek .pk.on{opacity:1}
@media(max-width:1024px){.peek{display:none}}

/* ---------- 12. IMAGE SLOTS (engraved placeholders) ---------- */
.slot{
  position:relative;width:100%;aspect-ratio:16/10;
  background:var(--ink);
  border:1px solid var(--line);
  overflow:hidden;display:grid;place-items:center;
}
.slot .dither-fill{position:absolute;inset:0;line-height:0;opacity:.9}
.slot .dither-fill canvas{width:100%;height:100%;object-fit:cover}
.slot canvas.dithered{position:absolute;inset:0}
.slot > img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* UI screenshots: show the whole screen, uncropped and undithered. The dither
   belongs on photography — run over an interface it eats the type, which is
   exactly the thing the screenshot is meant to prove. */
.slot.ui{background:var(--ink);padding:clamp(10px,1.4vw,22px)}
.slot.ui > img{position:relative;inset:auto;width:100%;height:100%;object-fit:contain}
.slot.ui .cap{display:none}
.slot .tick{position:absolute;width:11px;height:11px;border:0}
.slot .tick::before,.slot .tick::after{content:"";position:absolute;background:var(--vellum);opacity:.7}
.slot .tick::before{left:0;top:5px;width:11px;height:1px}
.slot .tick::after{top:0;left:5px;height:11px;width:1px}
.slot .tick.tl{top:9px;left:9px}.slot .tick.tr{top:9px;right:9px}
.slot .tick.bl{bottom:9px;left:9px}.slot .tick.br{bottom:9px;right:9px}
.slot .cap{
  font-family:var(--f-mono);font-size:.56rem;letter-spacing:.24em;text-transform:uppercase;
  color:var(--vellum);text-align:center;padding:.55rem .8rem;position:relative;z-index:1;
  background:var(--ink);border:1px solid rgba(233,231,224,.34);line-height:1.5;
}
.slot.has-img .cap{display:none}
.slot.tall{aspect-ratio:4/5}
.slot.phone{aspect-ratio:9/17.5;max-width:300px;margin-inline:auto}
.slot.square{aspect-ratio:1}
.slot.wide{aspect-ratio:21/9}

/* ---------- 13. CAPABILITIES ---------- */
.caps{border-top:var(--rule) solid var(--line)}
.cap-row{
  display:grid;grid-template-columns:5rem 1fr 1.2fr;gap:clamp(14px,2.4vw,40px);
  padding-block:clamp(18px,2.4vw,30px);
  border-bottom:var(--rule) solid var(--line);
  align-items:baseline;
}
.cap-row h3{font-family:var(--f-display-sm);font-size:clamp(1.3rem,2.3vw,2rem);font-weight:500;letter-spacing:.01em;line-height:1.16}
.cap-row p{font-family:var(--f-serif);color:var(--fg-muted);font-size:1.02rem;line-height:1.6}
@media(max-width:760px){.cap-row{grid-template-columns:3rem 1fr}.cap-row p{grid-column:2/-1}}

/* ---------- 14. APPROACH ---------- */
.tenets{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:1px;background:var(--line);border:1px solid var(--line)}
.tenet{background:var(--bg);padding:clamp(26px,2.8vw,42px);min-height:270px;display:flex;flex-direction:column;align-items:flex-start;gap:1.15rem;position:relative;overflow:hidden;transition:background .5s}
.tenet:hover{background:var(--bg-2)}
.tenet h4{font-family:var(--f-display-sm);font-size:clamp(1.2rem,1.8vw,1.6rem);font-weight:500;letter-spacing:.01em;line-height:1.2}
.tenet p{font-family:var(--f-serif);color:var(--fg-muted);font-size:.98rem;line-height:1.58}
.tenet .rose{position:absolute;bottom:-30px;right:-30px;width:126px;height:126px;opacity:.22;pointer-events:none}

/* ---------- 15. ABOUT ---------- */
.about-portrait{grid-column:1/5}
.about-copy{grid-column:6/12;display:flex;flex-direction:column;gap:1.4rem}
@media(max-width:860px){.about-portrait,.about-copy{grid-column:1/-1}}
.facts{display:grid;gap:0;border-top:var(--rule) solid var(--line);margin-top:.8rem}
.facts div{display:flex;justify-content:space-between;gap:1rem;padding-block:.72rem;border-bottom:var(--rule) solid var(--line)}

/* ---------- 16. CONTACT / FOOTER ---------- */
.contact{padding-block:clamp(70px,10vw,150px) 0}
.mailto{
  display:block;font-family:var(--f-display);font-weight:var(--display-weight);text-transform:none;
  font-size:clamp(1.8rem,8.2vw,7.6rem);line-height:1.06;letter-spacing:var(--display-track);
  padding-block:clamp(20px,3vw,40px);
  position:relative;overflow:hidden;
}
.mailto span{display:block;transition:transform .7s var(--e-out)}
.mailto:hover span{transform:translateY(-.03em)}
.mailto::after{content:"";position:absolute;left:0;bottom:14px;height:1px;width:100%;background:var(--fg);transform:scaleX(0);transform-origin:right;transition:transform .8s var(--e-out)}
.mailto:hover::after{transform:scaleX(1);transform-origin:left}

.ftr{
  display:flex;justify-content:space-between;align-items:flex-end;gap:2rem;flex-wrap:wrap;
  padding-block:clamp(26px,3vw,40px);border-top:var(--rule) solid var(--line);
}
.ftr .socials{display:flex;gap:1.4rem;flex-wrap:wrap}
.ftr .socials a{position:relative}
.ftr .socials a::after{content:"";position:absolute;left:0;bottom:-3px;height:1px;width:100%;background:var(--fg);transform:scaleX(0);transform-origin:right;transition:transform .5s var(--e-out)}
.ftr .socials a:hover::after{transform:scaleX(1);transform-origin:left}

/* ---------- 17. CASE STUDY PAGES ---------- */
.cs-hero{padding:clamp(120px,16vh,190px) var(--pad) 0}
.cs-hero .kicker{display:flex;gap:1.2rem;flex-wrap:wrap;color:var(--fg-faint);margin-bottom:clamp(20px,3vw,34px)}
.cs-hero h1{margin-bottom:clamp(22px,3vw,40px)}
.cs-meta{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  border-top:var(--rule) solid var(--line);
}
.cs-meta div{padding-block:1.1rem;padding-right:1.2rem;border-bottom:var(--rule) solid var(--line)}
.cs-meta dt{color:var(--fg-faint);margin-bottom:.5rem}
.cs-meta dd{font-size:.92rem;overflow-wrap:anywhere}

.cs-block{display:grid;grid-template-columns:repeat(12,1fr);gap:clamp(16px,2vw,28px);margin-bottom:clamp(40px,6vw,90px)}
.cs-block .label{grid-column:1/3}
.cs-block .content{grid-column:4/11;display:flex;flex-direction:column;gap:1.15rem}
.cs-block .content p{font-family:var(--f-serif);color:var(--fg-muted);font-size:clamp(.98rem,1.1vw,1.08rem);line-height:1.75}
.cs-block .content p strong{color:var(--fg);font-weight:500}
.cs-block .content h3{font-family:var(--f-display-sm);font-size:clamp(1.35rem,2.1vw,1.85rem);font-weight:500;letter-spacing:.01em;margin-top:.9rem}
@media(max-width:860px){.cs-block .label,.cs-block .content{grid-column:1/-1}}

.cs-list{display:flex;flex-direction:column;border-top:var(--rule) solid var(--line);margin-top:.6rem}
.cs-list li{list-style:none;display:flex;gap:1rem;padding-block:.85rem;border-bottom:var(--rule) solid var(--line);color:var(--fg-muted);font-family:var(--f-serif);font-size:1.02rem;line-height:1.55}
.cs-list li b{color:var(--fg);font-weight:500;font-family:var(--f-mono);font-size:.6rem;letter-spacing:.2em;padding-top:.35em;flex:none;width:2.4rem}

.gal{display:grid;gap:clamp(12px,1.6vw,22px);margin-bottom:clamp(40px,6vw,90px)}
.gal.two{grid-template-columns:repeat(2,1fr)}
.gal.three{grid-template-columns:repeat(3,1fr)}
@media(max-width:760px){.gal.two,.gal.three{grid-template-columns:1fr}}

.metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:1px;background:var(--line);border:1px solid var(--line)}
.metric{background:var(--bg);padding:clamp(20px,2.4vw,34px)}
.metric .v{font-family:var(--f-display);font-weight:var(--display-weight);font-size:clamp(2.1rem,4.2vw,3.6rem);line-height:1;letter-spacing:var(--display-track);margin-bottom:.7rem}
.metric .k{font-family:var(--f-serif);color:var(--fg-muted);font-size:.96rem;line-height:1.5}

.next{display:block;border-top:var(--rule) solid var(--line);padding-block:clamp(40px,6vw,90px)}
.next .n-in{display:flex;justify-content:space-between;align-items:flex-end;gap:2rem;transition:transform .8s var(--e-out)}
.next:hover .n-in{transform:translateX(14px)}
.next .n-name{font-family:var(--f-display);text-transform:none;font-size:clamp(1.8rem,6vw,5rem);line-height:1.04;letter-spacing:var(--display-track);font-weight:var(--display-weight)}
.next .n-name{transition:letter-spacing .6s var(--e-out)}
.next:hover .n-name{letter-spacing:.028em}

/* swatches for brand case study */
.swatches{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:1px;background:var(--line);border:1px solid var(--line)}
.sw{padding:clamp(16px,2vw,26px);aspect-ratio:1;display:flex;flex-direction:column;justify-content:flex-end;gap:.3rem}
.sw .hex{font-family:var(--f-mono);font-size:.58rem;letter-spacing:.16em}

.specimen{border:1px solid var(--line);padding:clamp(24px,3.4vw,54px);display:flex;flex-direction:column;gap:clamp(18px,2.4vw,32px)}
.specimen .glyphs{font-family:var(--f-display);font-size:clamp(2.2rem,7vw,5.6rem);line-height:1;letter-spacing:.01em;word-break:break-word}
.specimen .scale{display:flex;flex-direction:column;gap:.6rem}
.specimen .scale div{font-family:var(--f-display);line-height:1.05;letter-spacing:-.02em}

/* ---------- 18. DARK SECTIONS ---------- */
section[data-theme],div[data-theme],footer[data-theme]{
  background:var(--bg);color:var(--fg);
  transition:background .6s var(--e-io),color .6s var(--e-io);
}
.invert{background:var(--ink);color:var(--vellum)}

/* ---------- 19. REVEALS ---------- */
.rv{opacity:0;transform:translateY(26px);transition:opacity 1s var(--e-out),transform 1.1s var(--e-out)}
.rv.in{opacity:1;transform:none}
.rv-d1{transition-delay:.09s}.rv-d2{transition-delay:.18s}.rv-d3{transition-delay:.27s}.rv-d4{transition-delay:.36s}
.mask{overflow:hidden;display:block}
.mask > *{display:block;transform:translateY(105%);transition:transform 1.15s var(--e-out)}
.mask.in > *{transform:none}
/* Reveal-wipe.
   NB: this deliberately does NOT use clip-path on the element itself.
   IntersectionObserver measures the target's *clipped* area, so an element
   hidden with clip-path reports 0% visible, never crosses the threshold,
   never gets .in — and stays hidden forever. Deadlock. Instead a curtain
   pseudo-element covers it, leaving the element itself fully measurable. */
.wipe{position:relative}
.wipe::before{
  content:"";position:absolute;inset:-1px;z-index:4;pointer-events:none;
  background:var(--bg);transform-origin:top;
  transition:transform 1.15s var(--e-out);
}
.wipe.in::before{transform:scaleY(0)}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001ms!important;transition-duration:.001ms!important}
  .rv{opacity:1;transform:none}.mask > *{transform:none}.wipe::before{display:none}
}

/* ---------- 19b. SMALL SCREENS ---------- */
@media(max-width:640px){
  .hero-meta span:nth-child(2){display:none}
  .sec-head .aside{display:none}
  .cs-hero .kicker span:nth-child(2){display:none}
  .ftr{flex-direction:column;align-items:flex-start}
  .ftr .stack[style]{text-align:left!important}
}

/* ---------- 20. UTIL ---------- */
.mt-s{margin-top:1rem}.mt-m{margin-top:2rem}.mt-l{margin-top:clamp(30px,4vw,60px)}
.stack{display:flex;flex-direction:column;gap:1rem}
.row{display:flex;gap:1.2rem;flex-wrap:wrap;align-items:center}
.between{display:flex;justify-content:space-between;gap:1.4rem;flex-wrap:wrap}
.ornament{width:clamp(78px,8.5vw,136px);height:clamp(78px,8.5vw,136px);opacity:.7;flex:none}
.center-orn{display:grid;place-items:center;padding-block:clamp(30px,5vw,70px)}

/* ---------- 21. LATTICE / MOTIF PLACEMENT ---------- */
.section-lattice{position:relative;overflow:hidden}
.hdr .glyph{font-family:var(--f-display);font-weight:var(--display-weight);padding-bottom:0}

.specimen .glyphs{font-family:var(--f-display);font-weight:var(--display-weight)}
.specimen .scale div{font-family:var(--f-display);font-weight:var(--display-weight)}




/* ============================================================
   22. MANUSCRIPT LAYER
   Borders, bands, illuminated initials, ornamented rules.
   ============================================================ */

/* --- the page frame: a ruled border, the way a manuscript page is ruled --- */
.frame{position:fixed;inset:0;z-index:4;pointer-events:none}
.frame i{position:absolute;background:var(--line)}
.frame .t{top:11px;left:11px;right:11px;height:1px}
.frame .b{bottom:11px;left:11px;right:11px;height:1px}
.frame .l{left:11px;top:11px;bottom:11px;width:1px}
.frame .r{right:11px;top:11px;bottom:11px;width:1px}
.frame .t2{top:16px;left:16px;right:16px;height:1px;opacity:.45}
.frame .b2{bottom:16px;left:16px;right:16px;height:1px;opacity:.45}
.frame b{position:absolute;width:19px;height:19px;color:var(--fg);opacity:.55}
.frame b.c1{top:6px;left:6px}   .frame b.c2{top:6px;right:6px}
.frame b.c3{bottom:6px;left:6px}.frame b.c4{bottom:6px;right:6px}
@media(max-width:640px){.frame{display:none}}

/* --- horizontal ornament band: one row of the star lattice --- */
.band{
  position:relative;height:var(--band-h,46px);overflow:hidden;
  border-block:var(--rule) solid var(--line);
  color:var(--fg);opacity:.55;
}
.band.tall{--band-h:74px}
.band.faint{opacity:.3}

/* --- ornamented rule: hairline, tapering to a star at the centre --- */
.orn-rule{display:flex;align-items:center;gap:1.1rem;color:var(--fg)}
.orn-rule::before,.orn-rule::after{content:"";flex:1;height:1px;background:var(--line)}
.orn-rule i{display:block;width:clamp(34px,3.6vw,52px);height:clamp(34px,3.6vw,52px);opacity:.75;flex:none}
.orn-rule .sm{width:16px;height:16px;opacity:.5}

/* --- illuminated initial --- */
.dropcap{
  float:left;position:relative;
  width:clamp(84px,9vw,132px);aspect-ratio:1;
  margin:.28em 1.1rem .35rem 0;
  border:1px solid var(--fg);
  display:grid;place-items:center;overflow:hidden;
}
.dropcap .dc-lattice{position:absolute;inset:0;opacity:.3;color:var(--fg)}
.dropcap .dc-letter{
  position:relative;font-family:var(--f-display);font-weight:700;
  font-size:clamp(3.4rem,6vw,5.8rem);line-height:1;letter-spacing:0;
}
.dropcap::after{
  content:"";position:absolute;inset:5px;border:1px solid var(--fg);opacity:.4;
}
@media(max-width:560px){.dropcap{width:74px;margin-right:.9rem}}

/* --- numeral cartouche in section heads --- */
.sec-head .idx{
  position:relative;color:var(--fg);
  border:1px solid var(--line);padding:.42em .62em .38em;
  display:inline-flex;align-items:center;gap:.5rem;line-height:1;
}
.sec-head .idx::before,.sec-head .idx::after{
  content:"";position:absolute;top:50%;width:5px;height:5px;
  border:1px solid var(--line);transform:translateY(-50%) rotate(45deg);background:var(--bg);
}
.sec-head .idx::before{left:-3px}
.sec-head .idx::after{right:-3px}

/* --- dark sections carry their own lattice --- */
.sec-lattice{
  position:absolute;inset:0;pointer-events:none;color:var(--fg);opacity:.13;
  -webkit-mask-image:linear-gradient(180deg,#000,transparent 62%);
          mask-image:linear-gradient(180deg,#000,transparent 62%);
}
[data-theme="dark"] .sec-lattice{opacity:.2}

/* --- hero gets a ruled cartouche around the whole composition --- */
.hero-rule{position:absolute;left:var(--pad);right:var(--pad);height:1px;background:var(--line)}
.hero-rule.top{top:96px}

/* --- corner ticks on framed blocks --- */
.ticked{position:relative}
.ticked > .tk{position:absolute;width:13px;height:13px;color:var(--fg);opacity:.6}
.ticked > .tk.a{top:-7px;left:-7px}   .ticked > .tk.b{top:-7px;right:-7px}
.ticked > .tk.c{bottom:-7px;left:-7px}.ticked > .tk.d{bottom:-7px;right:-7px}


/* ============================================================
   23. POSTER LAYER
   1-bit screens, flyer metadata, hard contrast.
   ============================================================ */

/* --- halftone dot screen over the whole page --- */
.screen{
  position:fixed;inset:0;z-index:3;pointer-events:none;
  color:var(--fg);opacity:.055;
  background-image:radial-gradient(circle at 1px 1px, currentColor .7px, transparent 0);
  background-size:3px 3px;
}
[data-theme="dark"] .screen{opacity:.075}

/* --- flyer metadata: small mono blocks pinned to the edges --- */
.flyer{
  display:flex;justify-content:space-between;gap:1.4rem;flex-wrap:wrap;
  font-family:var(--f-mono);font-size:.6rem;letter-spacing:.22em;text-transform:uppercase;
  color:var(--fg-muted);line-height:1.7;
}
.flyer > div{max-width:38ch;min-width:19ch}
.flyer b{color:var(--fg);font-weight:400}
.flyer .rt{text-align:right}

/* --- poster hero: type at maximum, everything else pinned to the edges --- */
.hero-title{position:relative;z-index:2}
.hero-title .ln > span{display:block;margin-left:-.035em}

/* --- inverted block: white type knocked out of solid black --- */
.knock{background:var(--ink);color:var(--vellum);padding:clamp(18px,2.2vw,32px)}

/* --- hard rule: heavier than a hairline, poster weight --- */
.rule-hard{height:3px;background:var(--fg);width:100%;border:0}
.rule-med{height:1.5px;background:var(--fg);width:100%;border:0;opacity:.8}

/* --- drafting crosshairs at the grid intersections --- */
.marks{position:fixed;inset:0;z-index:2;pointer-events:none}
.marks i{position:absolute;width:9px;height:9px;opacity:.3}
.marks i::before,.marks i::after{content:"";position:absolute;background:var(--fg)}
.marks i::before{left:0;top:4px;width:9px;height:1px}
.marks i::after{top:0;left:4px;height:9px;width:1px}
@media(max-width:860px){.marks{display:none}}

/* --- section index tab, flyer style --- */
.tab{
  display:inline-block;background:var(--fg);color:var(--bg);
  font-family:var(--f-mono);font-size:.58rem;letter-spacing:.22em;text-transform:uppercase;
  padding:.42em .7em .38em;line-height:1;
}


/* ============================================================
   24. OUTLINE TYPE
   Celandine ships an outline cut as a second file; the browser can
   stroke any face and knock the fill out instead. Used on exactly two
   moments — both of which fill solid on hover, so the outline is a
   state rather than a decoration.
   ============================================================ */
.outline{
  color:transparent;
  -webkit-text-stroke:var(--outline-w) var(--fg);
  transition:color .55s var(--e-out), -webkit-text-stroke-color .55s var(--e-out);
}
.outline:hover,a:hover .outline{color:var(--fg)}

/* the huge email */
.mailto.outline span{color:inherit}
.mailto.outline:hover span{color:var(--fg)}

/* next-project title */
.next .n-name.outline{-webkit-text-stroke:var(--outline-w) var(--fg)}
.next:hover .n-name.outline{color:var(--fg)}

/* Firefox < 49 and anything without text-stroke gets solid type, not invisible */
@supports not (-webkit-text-stroke: 1px black){
  .outline{color:var(--fg)}
}
