/* Concept v2, Opal theme (owner-approved): outline nav pill, Newsreader subtext, case chapter rail. */

/* Site-wide compass filings sit behind everything. */
#field{position:fixed;inset:0;width:100vw;height:100vh;z-index:-1;pointer-events:none}
.hero,.case,.band,.contact,.p-hero,.story,.scrolly,.work,.evidence{background:transparent}

/* Header and sliding pill */
.top nav ul{position:relative;padding:4px;border-radius:999px}
.top nav li{position:relative;z-index:1}
.top nav a{border-radius:999px;transition:color .5s}
/* Every nav link is one fixed height with ~12px of space on all four sides of the text (13px type, 16px line). */
.top nav a{height:40px;min-height:0;padding:0 12px;line-height:1}
/* The pill takes its size and position from the active link, so it never stretches across wrapped rows. */
.navpill{position:absolute;top:0;left:0;width:0;height:40px;border-radius:999px;pointer-events:none;transition:left .7s cubic-bezier(.22,1,.36,1),top .7s cubic-bezier(.22,1,.36,1),width .7s cubic-bezier(.22,1,.36,1),transform .7s cubic-bezier(.22,1,.36,1)}
.navpill.moving{transform:scaleY(.88)}
/* Nav pill: outline, a thin white ring with a faint Opal glow. */
.navpill{background:transparent;box-shadow:inset 0 0 0 1px var(--pill-ring),0 0 14px var(--pill-glow)}
.top nav a.on{color:var(--fg)}

/* Tilt with Opal edge (UI screens) */
.tiltwrap{perspective:1200px}
.frame[data-tilt]{padding:1px;background:conic-gradient(from var(--ang,0deg),var(--o1),var(--o2),var(--o3),var(--o4),var(--o5),var(--o1));transform:rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));transition:transform .45s cubic-bezier(.2,.7,.2,1)}
.frame[data-tilt] img{background:#f4f4f2}
.frame[data-tilt]::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;background:radial-gradient(circle at var(--sx,50%) var(--sy,50%),rgb(255 255 255 / .14),transparent 45%);opacity:var(--sh,0);transition:opacity .3s}

/* Reading lens (dense boards) */
.lenshost{position:relative}
.frame[data-lens]{cursor:none}
/* Thick lens: a dark bevelled rim with red/cyan fringing at the very edge (chromatic aberration).
   The fringe sits only in the outer ring, so the magnified centre stays clean. */
.rlens{position:absolute;left:0;top:0;width:190px;height:190px;border-radius:50%;pointer-events:none;background-repeat:no-repeat;opacity:0;transition:opacity .2s;transform:translate(-50%,-50%);z-index:3;box-shadow:0 0 0 7px rgb(255 255 255 / .07),0 0 0 8px rgb(0 0 0 / .45),0 16px 44px rgb(0 0 0 / .5)}
.rlens::before{content:"";position:absolute;inset:0;border-radius:50%;background:radial-gradient(circle,transparent 76%,rgb(255 60 120 / .28) 84%,rgb(60 200 255 / .28) 90%,rgb(255 255 255 / .35) 96%,transparent 100%);box-shadow:inset 0 0 22px rgb(0 0 0 / .45),inset 3px 0 6px rgb(255 50 110 / .35),inset -3px 0 6px rgb(40 190 255 / .35)}
.rlens::after{content:"";position:absolute;inset:6%;border-radius:50%;background:radial-gradient(70% 45% at 30% 18%,rgb(255 255 255 / .35),transparent 60%)}
.rlens.on{opacity:1}

/* Stack peek: cycles on click, spreads with scroll */
.fan{position:relative;display:block;width:86%;aspect-ratio:1.278;border:0;padding:0;background:none;cursor:pointer}
.fan img{position:absolute;inset:0;width:100%;height:100%;border:1px solid var(--line);background:#f4f4f2;transition:transform .9s cubic-bezier(.22,1,.36,1)}
.fan img:nth-child(1){z-index:2;transform:translate(calc(var(--s,0)*-8px),calc(var(--s,0)*6px))}
.fan img:nth-child(2){z-index:1;transform:translate(calc(var(--s,0)*44px),calc(var(--s,0)*-22px)) rotate(calc(var(--s,0)*3deg))}
/* Hover or focus only; returns to rest when the pointer leaves, wherever the card sits on screen. */
.fan:hover,.fan:focus-visible{--s:1}

/* Rows for important-but-excess detail */
.rows{max-width:var(--max);margin:0 auto;padding:clamp(56px,10vh,110px) var(--gutter) 0}
.rows ul li{border-top:1px solid var(--line)}
.rows ul button{display:grid;grid-template-columns:auto 1fr auto;gap:16px;align-items:baseline;width:100%;padding:18px 0;background:none;border:0;color:inherit;font:inherit;text-align:left;cursor:pointer}
.rows .t{font-family:var(--display);font-variation-settings:'opsz' 48,'wdth' 85,'wght' 520;font-size:1.375rem;transition:transform .35s ease,color .35s}
.rows ul button:hover .t,.rows ul button[aria-expanded=true] .t{transform:translateX(8px);color:var(--o2)}
/* Row body sits after its button (button name = title only); hidden from everyone until opened. */
.rows .d{margin:0 0 0 32px;max-height:0;overflow:hidden;visibility:hidden;color:var(--soft);transition:max-height .45s ease,padding .45s ease,visibility 0s .45s}
.rows ul button[aria-expanded=true]+.d{max-height:160px;padding-bottom:18px;visibility:visible;transition:max-height .45s ease,padding .45s ease}

/* Experience chips under the hero subtext. */
.chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:18px}
.chips li{font-family:var(--mono);font-size:.75rem;color:var(--muted);padding:5px 10px;border-radius:999px;box-shadow:inset 0 0 0 1px var(--line-2);transition:color .3s,box-shadow .3s,transform .3s}
.chips li:hover{color:var(--fg);box-shadow:inset 0 0 0 1px var(--o2);transform:translateY(-2px)}

/* Proof rows: each strength links to the work that shows it, with a floating preview. */
.proofs{display:grid;align-self:end}
.proofs a{display:grid;grid-template-columns:auto 1fr;gap:2px 14px;padding:14px 0;border-top:1px solid var(--line);text-decoration:none}
.proofs .mono{grid-row:span 2;color:var(--o2);transition:transform .4s cubic-bezier(.22,1,.36,1)}
.proofs .pt{font-weight:500;transition:transform .4s cubic-bezier(.22,1,.36,1)}
.proofs .pd{font-size:.9375rem;color:var(--muted);transition:color .3s,transform .4s cubic-bezier(.22,1,.36,1)}
/* No sliding: the hovered row stays put and brightens while the others step back. */
.proofs:hover a:not(:hover) .pt,.proofs:hover a:not(:hover) .pd{opacity:.45}
.proofs .pt,.proofs .pd{transition:opacity .35s,color .35s}
.proofs a:hover .pd,.proofs a:focus-visible .pd{color:var(--o1)}
/* X-ray lens: the project sits hidden behind the proof rows; the thick lens reveals it, magnified, only under the cursor. */
.rlens.xray{position:fixed;z-index:40;background-color:#f4f4f2}
.proofs a{cursor:none}
body:has(.rlens.xray.on) :is(#halo,#dot){opacity:0}

/* Prototypes: Knight of the Realm leads. */
/* Featured row on its own (image left, text right); the other two share one aligned row below. */

/* Hero subtext: Newsreader, the three nouns in italic with a soft Opal underline. */
.lead2{margin-top:6px;max-width:30ch;color:var(--soft);font-family:'Newsreader',Georgia,serif;font-variation-settings:'opsz' 36;font-weight:350;font-size:clamp(1.6rem,2.4vw,2.25rem);line-height:1.18;letter-spacing:-.01em}
.lead2 b{color:var(--fg);background:var(--opal-soft) no-repeat 0 100%/100% 1px;padding-bottom:2px;font-weight:550;font-style:italic;font-variation-settings:'opsz' 36}

/* Case-page chapter rail (approved style): fixed in the left gutter; page content shifts right to make room. */
.caserail{position:fixed;left:var(--gutter);top:50%;transform:translateY(-50%);z-index:44;width:170px}
.caserail .label{color:var(--muted)}
html.has-caserail main{padding-left:200px}
@media (max-width:1100px){.caserail{display:none}html.has-caserail main{padding-left:0}}

/* Links draw a soft Opal underline; evidence items lift and replay their count. */
.cards .links a,.back,.foot a,.next .mono{text-decoration:none;background:var(--opal-soft) no-repeat 0 100%/0 1px;transition:background-size .5s ease,color .3s}
.cards .links a:hover,.cards .links a:focus-visible,.back:hover,.back:focus-visible,.foot a:hover,.foot a:focus-visible{background-size:100% 1px;color:var(--fg)}
.evidence a{position:relative;transition:transform .45s cubic-bezier(.22,1,.36,1)}
.evidence a::before{content:"";position:absolute;left:0;right:24px;top:-1px;height:1px;background:var(--opal-soft);transform:scaleX(0);transform-origin:0 50%;transition:transform .6s cubic-bezier(.22,1,.36,1)}
.evidence a:hover,.evidence a:focus-visible{transform:translateY(-4px)}
.evidence a:hover::before,.evidence a:focus-visible::before{transform:scaleX(1)}
.cta{transition:transform .5s cubic-bezier(.22,1,.36,1)}
.play{align-items:end}
/* Hero content sits in the vertical middle of the first screen instead of on its bottom edge. */
.hero{align-items:center;padding-top:clamp(32px,6vh,72px);padding-bottom:clamp(32px,6vh,72px)}
.play .tag{margin-left:10px;color:var(--muted)}

/* Less dead space between cases, quicker reveals, and slot-like snapping on the home page. */
.case{min-height:0;padding:clamp(40px,6vh,72px) 0}
.js [data-reveal]{transition-duration:.45s}
.js .case .frame{transition-duration:.6s}
@media (min-width:1001px){
  html:has(.work){scroll-snap-type:y mandatory}
  .hero,.evidence,.case,.band,.contact,.foot{scroll-snap-align:start}
  .case{scroll-snap-stop:always}
  html:has(.scrolly){scroll-snap-type:y proximity}
  .step,.p-hero,.story,.rows{scroll-snap-align:start}
}
@media (prefers-reduced-motion:reduce){html:has(.work){scroll-snap-type:y proximity}}

/* Soft sweep on subtext: word-level tint only, no movement */
.w{transition:color .4s}
@media (prefers-reduced-motion:reduce){.frame[data-tilt]{transform:none!important}}

/* Very narrow phones: one-line nav so the pill never wraps around two rows. */
@media (max-width:680px){.top nav ul{flex-wrap:nowrap}}
@media (max-width:420px){.top{gap:8px}.top nav ul{padding:3px}.top nav a{height:32px;padding:0 9px;font-size:.7rem}.navpill{height:32px}}

/* Prototypes: three equal columns in one row; image bottoms and titles line up (subgrid). */
.cards{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:1000px){.cards{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:680px){.cards{grid-template-columns:1fr}}
/* Away from the screen: owner asked for identical tiles, so these three are cropped to one square frame. */
.play .frame{aspect-ratio:1/1}
.play .frame img{object-fit:cover}
/* About: words on the left (title, links, stacked paragraphs); the rock portrait on the right, as tall as that whole column. */
.contact{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr);gap:clamp(32px,5vw,80px);align-items:stretch}
.contact .about{display:block;max-width:58ch}
.contact .about>div{margin-top:14px}
.contact .portrait{margin:0;min-height:0}
.contact .portrait .frame{aspect-ratio:auto;width:100%;height:100%}
.contact .portrait img{width:100%;height:100%;object-fit:cover;object-position:50% 40%}
@media (max-width:1000px){.contact{grid-template-columns:1fr}.contact .portrait{max-width:420px}.contact .portrait .frame{aspect-ratio:3/4;height:auto}}

/* Light mode: warm paper; Opal turns into a pearlescent black spectrum. Contrast checked in CHECKPOINT.md. */
html[data-mode="light"]{
  color-scheme:light;
  --bg:#f5f4f0;--bg-2:#ebe9e4;--fg:#121215;--soft:#47453f;--muted:#55524c;--quiet:#6b6862;
  --line:#d9d6cf;--line-2:#b9b5ac;
  --o1:#1e2540;--o2:#2b2038;--o3:#3a2030;--o4:#3a2a1e;--o5:#1b3a31;
  --opal-soft:linear-gradient(90deg,#171a26,#1d1726,#251821,#241c16,#15211d);
  --cta-ink:#f5f4f0;--top-bg:rgb(245 244 240 / .84);--viewer-bg:rgb(245 244 240 / .97);
  --halo-ring:rgb(43 32 56 / .45);--pill-ring:rgb(18 18 21 / .7);--pill-glow:rgb(43 32 56 / .12);
}
html[data-mode="light"] .cta-b{box-shadow:inset 0 1px 0 rgb(255 255 255 / .12)}
html[data-mode="light"] .cta:hover .cta-b{filter:brightness(1.25)}
/* Mode toggle: a small outline button that matches the nav pill. */
.mode{display:inline-grid;place-items:center;width:40px;height:40px;margin-left:6px;border:1px solid var(--line-2);border-radius:999px;background:none;color:var(--fg);cursor:pointer;flex:none}
.mode:hover,.mode:focus-visible{border-color:var(--fg)}
.mode svg{width:18px;height:18px}
.mode .sun{display:none}
html[data-mode="light"] .mode .sun{display:block}
html[data-mode="light"] .mode .moon{display:none}
@media (max-width:420px){.mode{width:32px;height:32px}}
html[data-mode="light"] .step{opacity:.86}
.top nav{margin-left:auto}

/* Intro: hide everything but the headline until fx.js takes over (head script removes this after 2.5s regardless). */
html.intro-pending .top .identity,html.intro-pending .top nav,html.intro-pending .hero-inner>p.mono,html.intro-pending .hero-row{opacity:0}
/* 320–360px: logo, four links and the mode toggle on one row without sideways scroll. */
@media (max-width:360px){.top{gap:6px}.top nav ul{padding:2px}.top nav a{padding:0 6px;font-size:.66rem}.mode{margin-left:2px}}
/* Light mode: the logo's hover fill is the pearlescent black, not the pale Opal. */
html[data-mode="light"] #opalfill stop:nth-child(1){stop-color:#171a26}
html[data-mode="light"] #opalfill stop:nth-child(2){stop-color:#251821}
html[data-mode="light"] #opalfill stop:nth-child(3){stop-color:#15211d}
/* Button-element CTAs (design system) reset the browser's button chrome. */
button.cta{padding:0;border:0;background:none;color:var(--fg);font:inherit;font-family:var(--mono);font-size:.875rem;font-weight:500;cursor:pointer}

/* Pause-motion button shares the toggle's look; its icon shows the action you'd take next. */
.mode.motion .play{display:none}
html[data-motion="paused"] .mode.motion .play{display:block}
html[data-motion="paused"] .mode.motion .pause{display:none}
.mode.motion+.mode{margin-left:6px}
/* Phones: links and round buttons keep a 44px tap area without changing their look (WCAG 2.5.5). */
@media (max-width:420px){.top nav a,.mode{position:relative}.top nav a::after,.mode::after{content:"";position:absolute;inset:-6px -2px}}
/* Desktop: 40px links and buttons get the same invisible 2px margin, so every target is at least 44px. */
.top nav a,.mode{position:relative}.top nav a::after,.mode::after{content:"";position:absolute;inset:-2px}
@media (max-width:420px){.top nav a::after,.mode::after{inset:-6px -2px}}
/* 320–360px with a mouse (e.g. 400% zoom) the header also holds the pause button: tighten the links a little more. */
@media (max-width:360px){.top nav a{padding:0 4px}.top .mode{width:32px;height:32px}.top{gap:4px}}
/* Hero chips are links to the work behind them; the whole pill is the target. */
.chips li:has(a){padding:0}
.chips a{display:inline-flex;align-items:center;min-height:28px;padding:5px 10px;border-radius:999px;color:inherit;text-decoration:none}
.chips li:has(a:focus-visible){color:var(--fg);box-shadow:inset 0 0 0 1px var(--o2)}
