/* Tokens. The three accents are the JWT segment colours: header, payload, signature. */
:root {
  color-scheme: light;
  --bg: #f4f5f7;
  --panel: #ffffff;
  --sunk: #eceef2;
  --ink: #12151b;
  --muted: #5b6472;
  --faint: #8a93a2;
  --line: #dde1e7;
  --hdr: #d92f38;
  --pay: #7c3aed;
  --sig: #0e9384;
  --on-sig: #ffffff;
  --display: 'Bricolage Grotesque', 'Helvetica Neue', Arial, sans-serif;
  --body: 'Geist', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --gutter: clamp(16px, 4vw, 48px);
  --ease: cubic-bezier(.2, .7, .1, 1);
  /* Glass surfaces */
  --glass-fill: linear-gradient(155deg, rgb(255 255 255 / .78), rgb(255 255 255 / .46) 50%, rgb(255 255 255 / .62));
  --glass-bar: rgb(244 245 247 / .55);
  --glass-line: rgb(15 20 30 / .09);
  --glass-hl: inset 0 1px 0 rgb(255 255 255 / .95), inset 0 0 0 1px rgb(255 255 255 / .45);
  --glass-drop: 0 24px 60px -30px rgb(20 25 45 / .35);
  /* Glass tint, 0 (clear) to 1 (tinted). The header's glass control sets it per visitor (glass.js); .45 is the default look. */
  --glass-tint: .45;
  --glass-blur: blur(calc(10px + var(--glass-tint) * 30px)) saturate(190%);
  /* Corner radii: one per kind of surface, so nested shapes line up. */
  --r-panel: 24px;  /* floating: dialogs, the sign-in card, the token inspector */
  --r-card: 20px;   /* cards and content blocks */
  --r-inner: 14px;  /* blocks inside a card: code, tokens, images, fields */
  --r-ctl: 12px;    /* buttons */
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #0d0f12; --panel: #14171c; --sunk: #1a1e25; --ink: #e8eaed; --muted: #9aa3b2; --faint: #6b7483; --line: #252a33;
    --hdr: #ff5a5f; --pay: #b57bff; --sig: #2bd4c4; --on-sig: #062b28;
    /* Liquid glass, in the manner of macOS 27: an even tint so text keeps its contrast, a light sheen from above. */
    --glass-fill: linear-gradient(135deg, rgb(255 255 255 / .13), rgb(255 255 255 / .04) 28%, rgb(255 255 255 / .015) 62%, rgb(255 255 255 / .06)), linear-gradient(color-mix(in srgb, var(--panel) calc(12% + var(--glass-tint) * 80%), transparent), color-mix(in srgb, var(--panel) calc(12% + var(--glass-tint) * 80%), transparent));
    --glass-bar: rgb(13 15 18 / calc(.2 + var(--glass-tint) * .5)); --glass-line: rgb(255 255 255 / .13);
    /* Rim: a bright specular edge on top, a fainter one below, a soft glow inside the top and light gathering at the bottom edge. */
    --glass-hl: inset 0 1px 0 rgb(255 255 255 / .32), inset 0 -1px 0 rgb(255 255 255 / .08), inset 0 0 0 1px rgb(255 255 255 / .04), inset 0 26px 40px -32px rgb(255 255 255 / .26), inset 0 -20px 30px -28px rgb(255 255 255 / .1);
    --glass-drop: 0 1px 2px rgb(0 0 0 / .3), 0 30px 70px -30px rgb(0 0 0 / .8);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0d0f12; --panel: #14171c; --sunk: #1a1e25; --ink: #e8eaed; --muted: #9aa3b2; --faint: #6b7483; --line: #252a33;
  --hdr: #ff5a5f; --pay: #b57bff; --sig: #2bd4c4; --on-sig: #062b28;
  /* Liquid glass, in the manner of macOS 27: an even tint so text keeps its contrast, a light sheen from above. */
    --glass-fill: linear-gradient(135deg, rgb(255 255 255 / .13), rgb(255 255 255 / .04) 28%, rgb(255 255 255 / .015) 62%, rgb(255 255 255 / .06)), linear-gradient(color-mix(in srgb, var(--panel) calc(12% + var(--glass-tint) * 80%), transparent), color-mix(in srgb, var(--panel) calc(12% + var(--glass-tint) * 80%), transparent));
    --glass-bar: rgb(13 15 18 / calc(.2 + var(--glass-tint) * .5)); --glass-line: rgb(255 255 255 / .13);
  /* Rim: a bright specular edge on top, a fainter one below, a soft glow inside the top and light gathering at the bottom edge. */
    --glass-hl: inset 0 1px 0 rgb(255 255 255 / .32), inset 0 -1px 0 rgb(255 255 255 / .08), inset 0 0 0 1px rgb(255 255 255 / .04), inset 0 26px 40px -32px rgb(255 255 255 / .26), inset 0 -20px 30px -28px rgb(255 255 255 / .1);
    --glass-drop: 0 1px 2px rgb(0 0 0 / .3), 0 30px 70px -30px rgb(0 0 0 / .8);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--bg); color: var(--ink); font-family: var(--body); font-size: 16px; line-height: 1.6; -webkit-font-smoothing: antialiased; }
a { color: inherit; }
button { font: inherit; color: inherit; cursor: pointer; }
:focus-visible { outline: 2px solid var(--sig); outline-offset: 3px; border-radius: 4px; }
[hidden] { display: none !important; }
.mono { font-family: var(--mono); }
.wrap { width: 100%; max-width: 1180px; margin-inline: auto; padding-inline: var(--gutter); }
.label { font-family: var(--mono); font-size: 12px; letter-spacing: .06em; text-transform: uppercase; color: var(--faint); }
.h-hdr { color: var(--hdr); } .h-pay { color: var(--pay); } .h-sig { color: var(--sig); }

/* Top bar: always shows the session state. */
.bar { position: sticky; top: 0; z-index: 30; background: color-mix(in srgb, var(--bg) 86%, transparent); backdrop-filter: blur(10px); border-bottom: 1px solid var(--line); padding-top: env(safe-area-inset-top, 0px); }
.bar-inner { display: flex; align-items: center; justify-content: space-between; height: 60px; gap: 16px; }
.brand { display: flex; align-items: center; gap: 10px; font-family: var(--mono); font-size: 13px; text-decoration: none; }
.brand { cursor: pointer; border-radius: 9px; }
.brand-mark { flex: none; display: block; border-radius: 7px; transition: transform 350ms var(--ease), box-shadow 350ms var(--ease); }
.brand-name, .brand-name span { transition: color 200ms; }
/* The logo is the way home: it lifts and glows on hover, presses in on click. */
.brand:hover .brand-mark, .brand:focus-visible .brand-mark { transform: translateY(-1px) rotate(-6deg) scale(1.08); box-shadow: 0 8px 20px -6px color-mix(in srgb, var(--pay) 70%, transparent), 0 0 0 1px color-mix(in srgb, var(--sig) 45%, transparent); }
.brand:active .brand-mark { transform: scale(.94); transition-duration: 120ms; }
.brand:hover .brand-name span, .brand:focus-visible .brand-name span { color: var(--sig); }
.brand:focus-visible { outline: 2px solid var(--sig); outline-offset: 4px; }
@media (prefers-reduced-motion: reduce) { .brand:hover .brand-mark, .brand:focus-visible .brand-mark, .brand:active .brand-mark { transform: none; } }
.brand-name { white-space: nowrap; }
.brand-name span { color: var(--muted); }
/* Small phones, landing page: the session pill needs the room, so the name drops its ".com". */
.pill-short { display: none; }
@media (max-width: 420px) {
  .bar-inner:has(#pill) .brand-name span { display: none; }
  .bar-inner:has(#pill) .brand { gap: 8px; }
  .bar-inner:has(#pill) .brand-mark { width: 24px; height: 24px; }
  .bar-inner:has(#pill) .session { gap: 6px; }
  /* Signed out, the pill says just "401", leaving room for the glass and theme buttons. */
  .pill-long { display: none; }
  .pill-short { display: inline; }
}
.session { display: flex; align-items: center; gap: 10px; font-family: var(--mono); font-size: 12px; color: var(--muted); }
.pill { display: inline-flex; align-items: center; gap: 8px; border: 1px solid var(--line); border-radius: 999px; padding: 5px 12px; background: var(--panel); white-space: nowrap; }
.pill .led { width: 7px; height: 7px; border-radius: 50%; background: var(--hdr); }
.pill.ok .led { background: var(--sig); box-shadow: 0 0 0 4px color-mix(in srgb, var(--sig) 20%, transparent); }
.link-btn { background: none; border: 0; padding: 0; color: var(--muted); text-decoration: underline; text-underline-offset: 3px; font-family: var(--mono); font-size: 12px; white-space: nowrap; }
.link-btn:hover { color: var(--ink); }
.nav { display: flex; gap: 4px; font-family: var(--mono); font-size: 13px; }
.nav a { white-space: nowrap; text-decoration: none; color: var(--ink); padding: 6px 12px; border-radius: 8px; transition: color 160ms, background 160ms; }
.nav a:hover { color: var(--ink); background: var(--sunk); }
.nav a[aria-current] { color: var(--ink); background: var(--sunk); }
/* Section links share one glass capsule; the section being read gets a teal pill (aria-current, set by the scroll spy). */
.nav-group { display: inline-flex; align-items: center; gap: 2px; padding: 3px; margin-right: 6px; border-radius: 999px;
  background: var(--glass-fill); border: 1px solid var(--glass-line); box-shadow: var(--glass-hl); }
.nav .nav-group a.in-app { font-size: 12px; padding: 5px 12px; border-radius: 999px; color: var(--muted); transition: color 160ms, background 200ms, box-shadow 200ms; }
.nav .nav-group a.in-app:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 7%, transparent); }
.nav .nav-group a.in-app[aria-current] { color: var(--ink); background: color-mix(in srgb, var(--sig) 18%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sig) 45%, transparent), inset 0 1px 0 rgb(255 255 255 / .12); }
body.gated .nav .nav-group { display: none; }
/* The timeline is for signed-in visitors: its link appears with the in-app links. */
body.gated .nav .nav-timeline { display: none; }
/* Signed out, Blogs is the only link: it sits on the right, beside the session pill. */
body.gated .nav { margin-left: auto; }
.nav .nav-out { margin-left: 6px; color: var(--ink); border: 1px solid var(--glass-line); border-radius: 999px; background: var(--glass-fill); box-shadow: var(--glass-hl); }
.nav .nav-out span { color: var(--sig); }
/* Landing page only: the Blogs pill invites a click. A token-coloured ring travels round it, the arrow nudges,
   and a dot shows when there's a recent post (script.js). */
@property --blogs-spin { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.nav .nav-blogs { position: relative; isolation: isolate; border-color: transparent; }
.nav-blogs::before, .nav-blogs::after { content: ''; position: absolute; inset: -1px; border-radius: inherit; pointer-events: none;
  background: conic-gradient(from var(--blogs-spin), var(--hdr), var(--pay), var(--sig), var(--pay), var(--hdr)); animation: blogs-spin 5s linear infinite; }
.nav-blogs::before { padding: 1.5px; -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; }
.nav-blogs::after { z-index: -1; filter: blur(9px); opacity: .32; transition: opacity 250ms; }
.nav-blogs:hover::after, .nav-blogs:focus-visible::after { opacity: .7; }
@keyframes blogs-spin { to { --blogs-spin: 360deg; } }
.nav-blogs .arr { display: inline-block; animation: blogs-nudge 3.2s var(--ease) infinite; }
.nav-blogs:hover .arr { animation: none; transform: translateX(3px); transition: transform 200ms; }
@keyframes blogs-nudge { 0%, 72%, 100% { transform: none; } 82% { transform: translateX(4px); } 90% { transform: translateX(-1px); } }
.nav-blogs .new-dot { position: absolute; top: -3px; right: -2px; width: 9px; height: 9px; border-radius: 50%; background: var(--sig); box-shadow: 0 0 0 2px var(--bg); }
.nav-blogs .new-dot::after { content: ''; position: absolute; inset: 0; border-radius: 50%; background: var(--sig); animation: blogs-ping 2s ease-out infinite; }
@keyframes blogs-ping { 0% { transform: scale(1); opacity: .7; } 100% { transform: scale(2.6); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .nav-blogs::before, .nav-blogs::after, .nav-blogs .arr, .nav-blogs .new-dot::after { animation: none; } }
.consent-q code { font-family: var(--mono); font-size: 13px; color: var(--pay); }

/* Backdrop: a faint grid lit by the three token colours, shown behind the gate. */
.backdrop { position: fixed; inset: 0; z-index: 0; pointer-events: none; opacity: 1; transition: opacity 700ms var(--ease);
  background:
    radial-gradient(560px circle at 15% 35%, color-mix(in srgb, var(--hdr) 17%, transparent), transparent 70%),
    radial-gradient(520px circle at 85% 45%, color-mix(in srgb, var(--sig) 15%, transparent), transparent 70%),
    radial-gradient(680px circle at 50% 105%, color-mix(in srgb, var(--pay) 17%, transparent), transparent 70%); }
/* A grid floor in perspective, drifting toward the viewer. */
.backdrop { overflow: hidden; }
.backdrop::before { content: ''; position: absolute; left: -60%; right: -60%; bottom: 0; height: 62%; opacity: .7;
  background-image: linear-gradient(color-mix(in srgb, var(--pay) 30%, var(--line)) 1px, transparent 1px), linear-gradient(90deg, color-mix(in srgb, var(--pay) 30%, var(--line)) 1px, transparent 1px);
  background-size: 64px 64px;
  transform: perspective(420px) rotateX(64deg); transform-origin: 50% 100%;
  -webkit-mask-image: linear-gradient(to top, #000 0%, transparent 90%); mask-image: linear-gradient(to top, #000 0%, transparent 90%);
  animation: floor 5s linear infinite; }
@keyframes floor { to { background-position: 0 64px; } }
body:not(.gated) .backdrop { opacity: .6; }
body:not(.gated) .backdrop::before { display: none; }
body.gated .backdrop { opacity: 1; }
.gate, .app, .writing, body > footer.site { position: relative; z-index: 1; }

/* ── Gate: 401 → consent → token ─────────────────────────────── */
.gate { min-height: calc(100svh - 61px); display: grid; place-items: center; padding-block: clamp(20px, 5vh, 72px); }
/* "Skip the show": a quiet way past the animation, centred at the foot of the gate. */
.gate { position: relative; }
.skip-show { position: absolute; left: 0; right: 0; bottom: clamp(12px, 3vh, 28px); margin: 0; text-align: center; }
/* A glass pill: easy to spot, but quieter than Enter as guest. */
.skip-btn { display: inline-flex; align-items: center; gap: 6px; padding: 9px 18px; border-radius: 999px; font-family: var(--mono); font-size: 13.5px; color: var(--sig);
  background: var(--glass-fill); border: 1px solid color-mix(in srgb, var(--sig) 40%, var(--glass-line)); box-shadow: var(--glass-hl), 0 10px 30px -14px color-mix(in srgb, var(--sig) 55%, transparent);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); transition: border-color 160ms, box-shadow 200ms; }
.skip-btn .q { color: var(--ink); }
.skip-btn .arr { display: inline-block; transition: transform 200ms var(--ease); }
.skip-btn:hover { border-color: var(--sig); box-shadow: var(--glass-hl), 0 12px 34px -12px color-mix(in srgb, var(--sig) 75%, transparent); }
.skip-btn:hover .arr { transform: translateX(3px); }
.gate-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 440px); gap: clamp(32px, 6vw, 80px); align-items: center; width: 100%; }
/* 3D status code: front face + stacked layers in Z, tilted by script.js (--rx / --ry). */
.code3d { position: relative; perspective: 900px; margin: 0 0 4px; padding-block: 8px 18px; font-family: var(--display); font-weight: 800; font-size: clamp(88px, min(15vw, 21vh), 196px); line-height: .85; letter-spacing: -.04em; user-select: none; }
.code3d-tilt { display: inline-flex; transform-style: preserve-3d; transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); will-change: transform; }
.digit { position: relative; display: inline-block; transform-style: preserve-3d; }
.digit b, .digit i { font: inherit; font-style: normal; display: block; }
.digit b { position: relative; transform: translateZ(1px); color: var(--tone);
  background: linear-gradient(105deg, var(--tone) 0 38%, color-mix(in srgb, var(--tone) 55%, #fff) 48%, var(--tone) 58% 100%);
  background-size: 260% 100%; background-position: var(--glare, 50%) 0; -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.digit i { position: absolute; inset: 0; pointer-events: none; }
.code3d-shadow { position: absolute; left: 4%; bottom: 0; width: min(520px, 70%); height: 22px; border-radius: 50%; background: radial-gradient(closest-side, rgb(0 0 0 / .45), transparent); filter: blur(4px); transform: translateX(calc(var(--ry, 0deg) / 1deg * -2px)); }
.status-code { font-family: var(--display); font-weight: 800; font-size: clamp(88px, 14vw, 184px); line-height: .85; letter-spacing: -.04em; margin: 0; }
.status-code span { color: var(--hdr); }
.gate h1 { font-family: var(--display); font-weight: 700; font-size: clamp(30px, 4vw, 52px); line-height: 1.05; letter-spacing: -.025em; margin: 18px 0 14px; text-wrap: balance; }
.gate .lede { color: var(--muted); max-width: 46ch; margin: 0 0 24px; }
.log { font-family: var(--mono); font-size: 13px; line-height: 1.9; color: var(--muted); border-left: 2px solid var(--line); padding-left: 16px; margin: 0; min-height: 5.7em; white-space: pre-wrap; overflow-wrap: anywhere; }
.log b { font-weight: 500; color: var(--ink); }

.card { background: var(--panel); border: 1px solid var(--line); border-radius: 16px; padding: clamp(20px, 3vw, 28px); box-shadow: 0 30px 60px -40px rgb(0 0 0 / .35); }
.idp-head { display: flex; align-items: center; gap: 14px; padding-bottom: 16px; border-bottom: 1px solid var(--line); }
.avatar { width: 52px; height: 52px; border-radius: 50%; object-fit: cover; border: 2px solid var(--panel); box-shadow: 0 0 0 2px var(--sig); flex: none; }
.idp-head h2 { margin: 0; font-size: 17px; font-weight: 600; letter-spacing: -.01em; }
.verified { display: inline-flex; align-items: center; gap: 5px; font-family: var(--mono); font-size: 11px; color: var(--sig); }
.consent-q { margin: 16px 0 10px; font-size: 15px; }
.consent-q b { font-weight: 600; }
.consent-q { margin-bottom: 12px; }
/* Says up front that this is a demo, not a real login. */
.demo-chip { display: inline-flex; align-items: center; gap: 8px; margin: 0 0 16px; padding: 4px 11px; border-radius: 999px; font-family: var(--mono); font-size: 11.5px; color: var(--sig);
  background: color-mix(in srgb, var(--sig) 10%, transparent); border: 1px solid color-mix(in srgb, var(--sig) 35%, transparent); }
.demo-chip .led { width: 6px; height: 6px; border-radius: 50%; background: var(--sig); }
/* Once, as the card arrives: a soft teal glow swells round the chip and fades, then it settles to its normal look.
   Only the glow layer's opacity animates. Off with reduced motion. */
.demo-chip { position: relative; }
.demo-chip::after { content: ''; position: absolute; inset: -1px; border-radius: inherit; pointer-events: none; opacity: 0;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--sig) 70%, transparent), 0 0 18px 3px color-mix(in srgb, var(--sig) 45%, transparent);
  animation: demo-glow 2.6s ease-out 1.5s both; }
@keyframes demo-glow { 0% { opacity: 0; } 25% { opacity: 1; } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .demo-chip::after { animation: none; } }
/* Scopes, folded: a single row that opens into the list. */
.scope-picker > summary { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 12px; border-radius: var(--r-ctl); cursor: pointer; list-style: none; font-size: 14px;
  border: 1px solid var(--glass-line); background: var(--glass-fill); box-shadow: var(--glass-hl); transition: border-color 160ms; }
.scope-picker > summary::-webkit-details-marker { display: none; }
.scope-picker > summary:hover { border-color: color-mix(in srgb, var(--pay) 45%, var(--glass-line)); }
.scope-picker > summary i { font-style: normal; color: var(--muted); }
.scope-sum { font-family: var(--mono); font-size: 12px; color: var(--pay); white-space: nowrap; }
.scope-sum::after { content: ' ▾'; }
.scope-picker[open] .scope-sum::after { content: ' ▴'; }
.scope-picker[open] > summary { margin-bottom: 8px; }
.scopes { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.scope { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 12px; align-items: center; padding: 8px 12px; border: 1px solid var(--line); border-radius: var(--r-ctl); cursor: pointer; transition: border-color 160ms, background 160ms; }
.scope:hover { border-color: var(--faint); }
.scope:has(input:checked) { border-color: color-mix(in srgb, var(--pay) 55%, var(--line)); background: color-mix(in srgb, var(--pay) 6%, transparent); }
.scope input { width: 16px; height: 16px; margin: 0; accent-color: var(--pay); }
.scope code { font-family: var(--mono); font-size: 13px; color: var(--pay); }
.scope > div { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.scope span { font-size: 13px; color: var(--muted); line-height: 1.45; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.scope.fixed { cursor: default; background: var(--sunk); }
.scope.fixed .tick { width: 16px; height: 16px; margin-top: 0; border-radius: 4px; display: grid; place-items: center; color: var(--muted); font-size: 12px; border: 1px solid var(--line); }
.actions { display: flex; gap: 10px; margin-top: 16px; }
.btn { border-radius: var(--r-ctl); padding: 11px 18px; font-weight: 500; font-size: 15px; border: 1px solid var(--line); background: var(--panel); transition: transform 120ms, background 160ms, border-color 160ms; }
.btn:hover { border-color: var(--faint); }
.btn:active { transform: translateY(1px); }
.btn.primary { flex: 1; background: var(--sig); border-color: var(--sig); color: var(--on-sig); }
.btn.primary:hover { filter: brightness(1.06); }
.fine { margin: 14px 0 0; font-size: 12px; color: var(--faint); }
.denied { text-align: center; padding-block: 18px; }
.denied p { color: var(--muted); }

/* Token minting */
.gate-side { display: grid; align-content: center; }
#consent.leaving { animation: consent-out 320ms ease-in both; }
@keyframes consent-out { to { opacity: 0; transform: translateY(-10px) scale(.96); filter: blur(6px); } }
.mint { display: grid; gap: 14px; align-content: center; }
.mint-status { justify-self: start; display: inline-flex; align-items: center; gap: 10px; margin: 0; padding: 7px 14px; border-radius: 999px; font-family: var(--mono); font-size: 12px; color: var(--muted);
  background: var(--glass-fill); border: 1px solid var(--glass-line); box-shadow: var(--glass-hl), var(--glass-drop); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); }
.mint-status .led { width: 7px; height: 7px; border-radius: 50%; background: var(--sig); animation: pulse 1.2s ease-in-out infinite; }
@keyframes pulse { 50% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--sig) 25%, transparent); } }
.mint-status b { color: var(--sig); font-weight: 500; padding-left: 10px; border-left: 1px solid var(--glass-line); }
.token-card { padding: 18px 20px; background: var(--glass-fill); border: 1px solid var(--glass-line); box-shadow: var(--glass-hl), var(--glass-drop); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); }
.token-card:not([hidden]) { animation: jwt-in 450ms var(--ease) both; }
.token-card .label { margin: 0; }
.token-card .jwt { background: none; box-shadow: none; padding: 0; margin-top: 10px; }
/* Token forge: three segments on a tilted plane that flattens into the finished JWT. */
.forge { perspective: 1800px; }
/* A gentle backward tilt only: no sideways lean or twist, so the stack stays square to its column. */
.forge-plane { display: grid; gap: 14px; transform-style: preserve-3d; transform: rotateX(10deg); transform-origin: 50% 0; transition: transform 650ms var(--ease); }
.forge.in .forge-plane { animation: forge-in 650ms var(--ease) both; }
@keyframes forge-in { from { opacity: 0; transform: rotateX(70deg) translateY(30px) scale(.9); } }
.forge.flat .forge-plane { transform: none; }
.forge.out { opacity: 0; transform: scale(.97); transition: opacity 260ms, transform 260ms; }
.seg { --z: 0px; position: relative; padding: 14px 16px; border-radius: var(--r-inner); background: var(--sunk); border: 1px solid color-mix(in srgb, var(--c) 35%, var(--line));
  box-shadow: 0 22px 34px -22px color-mix(in srgb, var(--c) 70%, transparent); transform: translateZ(var(--z)); opacity: .18; transition: opacity 300ms, transform 650ms var(--ease), border-color 300ms; }
.seg-h { --c: var(--hdr); --z: 10px; } .seg-p { --c: var(--pay); --z: 5px; } .seg-s { --c: var(--sig); }
.seg.on { opacity: 1; }
.seg.enc { border-color: var(--c); }
.forge.flat .seg { transform: none; box-shadow: none; }
.seg-label { font-family: var(--mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--c); }
.seg pre { margin: 6px 0 0; font-family: var(--mono); font-size: 12px; line-height: 1.5; color: var(--muted); white-space: pre-wrap; word-break: break-all; min-height: 1.5em; }
.seg pre .k { color: var(--pay); } .seg pre .s { color: var(--ink); } .seg pre .n { color: var(--hdr); }
.seg.enc pre { color: var(--c); }
@keyframes jwt-in { from { opacity: 0; transform: translateY(8px); } }
.jwt { font-family: var(--mono); font-size: 12.5px; line-height: 1.55; word-break: break-all; background: var(--sunk); border-radius: var(--r-inner); padding: 14px; margin: 10px 0 0; }
.jwt .p1 { color: var(--hdr); } .jwt .p2 { color: var(--pay); } .jwt .p3 { color: var(--sig); } .jwt .dot { color: var(--ink); }

/* ── Unlocked content ─────────────────────────────────────────── */
.app section { padding-block: clamp(44px, 7vw, 96px); border-top: 1px solid var(--line); scroll-margin-top: 61px; }
.sec-head { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; margin-bottom: clamp(24px, 4vw, 40px); }
.sec-head h2 { font-family: var(--display); font-weight: 700; font-size: clamp(34px, 5vw, 64px); line-height: 1; letter-spacing: -.03em; margin: 8px 0 0; text-wrap: balance; }
.route { font-family: var(--mono); font-size: 12px; color: var(--muted); white-space: nowrap; }
.route b { font-weight: 500; color: var(--sig); }

.hello { padding-block: clamp(48px, 7vw, 88px) clamp(40px, 6vw, 72px); }
.hello h1 { font-family: var(--display); font-weight: 800; font-size: clamp(48px, 9vw, 128px); line-height: .92; letter-spacing: -.045em; margin: 14px 0 20px; }
.hello h1 .sub { display: block; color: var(--muted); font-weight: 500; font-size: .42em; letter-spacing: -.02em; margin-top: 14px; }
.hello p { max-width: 60ch; color: var(--muted); font-size: 18px; margin: 0; }
.cta { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 26px; }
a.btn { display: inline-flex; align-items: center; gap: 8px; text-decoration: none; }
.cta .btn.primary { flex: none; }
.granted-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.granted-list span { font-family: var(--mono); font-size: 12px; padding: 4px 10px; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--pay) 40%, var(--line)); color: var(--pay); }

/* Locked */
.locked { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 18px; align-items: center; border: 1px dashed var(--line); border-radius: var(--r-card); padding: 22px; background: repeating-linear-gradient(-45deg, transparent 0 10px, color-mix(in srgb, var(--hdr) 4%, transparent) 10px 20px); }
.locked svg { width: 28px; height: 28px; color: var(--hdr); }
.locked b { font-family: var(--mono); font-weight: 500; color: var(--hdr); }
.locked p { margin: 2px 0 0; color: var(--muted); font-size: 14px; }

/* About: identity claims */
.about { display: grid; grid-template-columns: minmax(0, 360px) minmax(0, 1fr); gap: clamp(24px, 5vw, 64px); align-items: start; }
.idcard { position: relative; border-radius: 16px; overflow: hidden; background: var(--panel); border: 1px solid var(--line); }
.idcard img { display: block; width: 100%; aspect-ratio: 4 / 4.6; object-fit: cover; object-position: 50% 30%; }
.idcard .stamp { position: absolute; top: 14px; right: 14px; font-family: var(--mono); font-size: 11px; color: var(--sig); background: var(--panel); border: 1px solid var(--sig); border-radius: 6px; padding: 3px 8px; transform: rotate(-4deg); }
.idcard footer { display: flex; justify-content: space-between; padding: 12px 16px; font-family: var(--mono); font-size: 11px; color: var(--faint); border-top: 1px solid var(--line); }
.claims { font-family: var(--mono); font-size: 14px; background: var(--panel); border: 1px solid var(--line); border-radius: 16px; padding: clamp(18px, 3vw, 28px); margin: 0; line-height: 2; white-space: pre-wrap; overflow-wrap: anywhere; }
/* One block per claim, with a hanging indent so wrapped values stay inside the object. */
.claims .cl { display: block; padding-left: 4ch; text-indent: -2ch; }
.claims .brace { display: block; }
.claims .k { color: var(--pay); } .claims .s { color: var(--ink); } .claims .n { color: var(--hdr); } .claims .c { color: var(--faint); }
.about-copy { margin-top: 22px; color: var(--muted); max-width: 62ch; }

/* Work: protected resources */
.resources { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.res { position: relative; overflow: hidden; background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 22px; display: grid; gap: 10px; align-content: start; transition: border-color 200ms, transform 300ms var(--ease), box-shadow 300ms var(--ease); }
/* Token-coloured edge that draws in on hover. */
.res::after { content: ''; position: absolute; inset: 0 0 auto; height: 2px; background: linear-gradient(90deg, var(--hdr), var(--pay), var(--sig)); transform: scaleX(0); transform-origin: left; transition: transform 500ms var(--ease); }
.res:hover::after { transform: scaleX(1); }
.res:hover { border-color: color-mix(in srgb, var(--sig) 60%, var(--line)); transform: translateY(-3px); box-shadow: 0 24px 48px -32px rgb(0 0 0 / .5); }
.res .req span:last-child { color: var(--sig); }
.res .req { font-family: var(--mono); font-size: 12px; color: var(--muted); display: flex; justify-content: space-between; gap: 12px; }
.res .req b { color: var(--sig); font-weight: 500; }
.res h3 { margin: 0; font-family: var(--display); font-weight: 700; font-size: 26px; letter-spacing: -.02em; line-height: 1.1; }
.res p { margin: 0; color: var(--muted); font-size: 15px; }
/* Company on a work card: a small purple pill, the colour of identity claims (teal is for status). */
.res .org { margin: -2px 0 0; font-family: var(--mono); font-size: 12px; }
.res .org > a, .res .org > span { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: 999px; color: var(--pay); text-decoration: none;
  background: color-mix(in srgb, var(--pay) 10%, transparent); border: 1px solid color-mix(in srgb, var(--pay) 30%, transparent); transition: background 160ms, border-color 160ms; }
.res .org > a:hover { background: color-mix(in srgb, var(--pay) 18%, transparent); border-color: color-mix(in srgb, var(--pay) 60%, transparent); }
.res .metric { font-family: var(--mono); font-size: 12px; color: var(--sig); }

/* Personal projects: live, clickable cards. */
.live-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.res.live { grid-template-rows: auto auto auto 1fr auto auto; }
.res .req .up { display: inline-flex; align-items: center; gap: 6px; }
.res .req .up i { width: 7px; height: 7px; border-radius: 50%; background: var(--sig); box-shadow: 0 0 0 3px color-mix(in srgb, var(--sig) 22%, transparent); }
.res .kicker { margin-top: -4px; font-size: 14px; color: var(--pay); }
.res .open { justify-self: start; margin-top: 6px; font-family: var(--mono); font-size: 13px; color: var(--sig); text-decoration: none; }
.res .open::before { content: ''; position: absolute; inset: 0; border-radius: inherit; }
.res:hover .open { text-decoration: underline; text-underline-offset: 3px; }
.tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.tags span { font-family: var(--mono); font-size: 11px; color: var(--muted); border: 1px solid var(--line); border-radius: 6px; padding: 2px 7px; }

/* Skills: grouped like OAuth scopes */
.scope-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.scope-card { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 20px; }
.scope-card.ai { border-color: color-mix(in srgb, var(--pay) 45%, var(--line)); background: linear-gradient(160deg, color-mix(in srgb, var(--pay) 9%, var(--panel)), var(--panel) 60%); }
.scope-name { display: flex; justify-content: space-between; gap: 12px; margin: 0; font-family: var(--mono); font-size: 12px; color: var(--faint); }
.scope-name code { color: var(--pay); }
.scope-card h3 { margin: 8px 0 14px; font-family: var(--display); font-weight: 700; font-size: 22px; letter-spacing: -.02em; line-height: 1.15; }
.chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.chips li { font-size: 13px; padding: 4px 10px; border-radius: 999px; background: var(--sunk); border: 1px solid var(--line); }
.scope-card.ai .chips li { border-color: color-mix(in srgb, var(--pay) 35%, var(--line)); }

/* Writing: audit log */
.audit { list-style: none; margin: 0; padding: 0; border: 1px solid var(--line); border-radius: 14px; background: var(--panel); overflow: hidden; }
.audit a { display: grid; grid-template-columns: 112px 130px minmax(0, 1fr) auto; gap: 16px; align-items: baseline; padding: 16px 20px; text-decoration: none; border-bottom: 1px solid var(--line); transition: background 160ms; }
.audit li:last-child a { border-bottom: 0; }
.audit a:hover { background: var(--sunk); }
.audit time, .audit .cat { font-family: var(--mono); font-size: 12px; color: var(--faint); }
.audit .cat { color: var(--pay); }
.audit h3 { margin: 0; font-size: 17px; font-weight: 500; letter-spacing: -.01em; }
.audit .go { font-family: var(--mono); font-size: 12px; color: var(--sig); white-space: nowrap; }

.all-posts { display: inline-flex; gap: 8px; margin-top: 16px; font-family: var(--mono); font-size: 13px; color: var(--sig); text-decoration: none; }
.all-posts:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ── /writing/ ───────────────────────────────────────────────── */
.writing { padding-block: clamp(48px, 7vw, 88px) clamp(56px, 8vw, 104px); }
.w-head h1 { font-family: var(--display); font-weight: 800; font-size: clamp(56px, 10vw, 136px); line-height: .9; letter-spacing: -.045em; margin: 14px 0 18px; }
.w-head .lede { color: var(--muted); font-size: 18px; max-width: 56ch; margin: 0; }
.filters { display: flex; flex-wrap: wrap; gap: 8px; margin: clamp(28px, 4vw, 44px) 0 clamp(24px, 4vw, 40px); position: sticky; top: 61px; z-index: 5; padding-block: 12px; background: color-mix(in srgb, var(--bg) 92%, transparent); backdrop-filter: blur(10px); }
.filters button { display: inline-flex; align-items: center; gap: 8px; font-family: var(--mono); font-size: 13px; padding: 7px 14px; border-radius: 999px; border: 1px solid var(--line); background: var(--panel); color: var(--muted); transition: color 160ms, border-color 160ms, background 160ms; }
.filters button span { font-size: 11px; color: var(--faint); }
.filters button:hover { color: var(--ink); border-color: var(--faint); }
.filters button[aria-pressed="true"] { color: var(--pay); border-color: color-mix(in srgb, var(--pay) 55%, var(--line)); background: color-mix(in srgb, var(--pay) 8%, var(--panel)); }
.filters button[aria-pressed="true"] span { color: var(--pay); }
.year + .year { margin-top: clamp(32px, 5vw, 56px); }
.year > .label { margin: 0 0 14px; }
.posts { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.post { position: relative; display: grid; gap: 8px; padding: clamp(18px, 3vw, 24px); background: var(--panel); border: 1px solid var(--line); border-radius: 14px; text-decoration: none; overflow: hidden; transition: border-color 200ms, transform 300ms var(--ease), box-shadow 300ms var(--ease); }
.post::after { content: ''; position: absolute; inset: 0 0 auto; height: 2px; background: linear-gradient(90deg, var(--hdr), var(--pay), var(--sig)); transform: scaleX(0); transform-origin: left; transition: transform 500ms var(--ease); }
.post:hover { border-color: color-mix(in srgb, var(--sig) 60%, var(--line)); transform: translateY(-2px); box-shadow: 0 24px 48px -32px rgb(0 0 0 / .5); }
.post:hover::after { transform: scaleX(1); }
.post .meta { display: flex; flex-wrap: wrap; gap: 6px 16px; margin: 0; font-family: var(--mono); font-size: 12px; color: var(--faint); }
.post .meta .cat { color: var(--pay); }
.post h3 { margin: 0; font-family: var(--display); font-weight: 700; font-size: clamp(22px, 2.6vw, 28px); letter-spacing: -.02em; line-height: 1.15; }
.post .summary { margin: 0; color: var(--muted); max-width: 70ch; }
.post .read { font-family: var(--mono); font-size: 12px; color: var(--sig); }

/* Contact */
.elevate { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 420px); gap: clamp(24px, 5vw, 64px); align-items: center; }
.elevate h2 { font-family: var(--display); font-weight: 800; font-size: clamp(40px, 6vw, 84px); line-height: .95; letter-spacing: -.04em; margin: 10px 0 16px; text-wrap: balance; }
.elevate p { color: var(--muted); margin: 0; max-width: 46ch; }
.mailbox { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-family: var(--mono); font-size: 15px; background: var(--sunk); border-radius: var(--r-inner); padding: 12px 14px; margin: 14px 0; user-select: all; }
.links { display: flex; flex-wrap: wrap; gap: 8px; }
.links a { font-family: var(--mono); font-size: 13px; text-decoration: none; border: 1px solid var(--line); border-radius: var(--r-ctl); padding: 8px 12px; }
.links a:hover { border-color: var(--sig); color: var(--sig); }

/* Token inspector (floating) */
.inspector { position: fixed; z-index: 40; right: var(--gutter); bottom: calc(16px + env(safe-area-inset-bottom, 0px)); display: flex; flex-direction: column; align-items: flex-end; }
.inspector > button { display: flex; }
/* jwt.io-style: encoded token on the left, decoded parts on the right */
.inspector .panel { order: -1; width: min(880px, calc(100vw - 2 * var(--gutter))); margin-bottom: 10px; padding: 18px 20px; border-radius: var(--r-panel); border: 1px solid var(--line);
  box-shadow: 0 30px 60px -30px rgb(0 0 0 / .45); max-height: min(78vh, 680px); overflow: auto; animation: insp-in 260ms var(--ease) both; }
@keyframes insp-in { from { opacity: 0; transform: translateY(10px) scale(.98); } }
.insp-top { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 14px; }
.insp-top .label { margin: 0; }
.insp-actions { display: flex; gap: 14px; }
.insp-grid { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); gap: 16px; }
.insp-grid > section { min-width: 0; }
.insp-grid > section > .label { margin: 0 0 8px; }
.insp-enc .jwt { margin: 0; padding: 16px; font-size: 13px; line-height: 1.7; border-radius: var(--r-inner); background: color-mix(in srgb, var(--sunk) 70%, transparent); border: 1px solid var(--line); }
.insp-enc { display: flex; flex-direction: column; }
.insp-enc .jwt { flex: 1; }
.insp-legend { margin: 10px 0 0; font-family: var(--mono); font-size: 11px; color: var(--faint); }
.insp-part { padding: 10px 14px 12px; margin-bottom: 10px; border-radius: var(--r-inner); border: 1px solid var(--line); background: color-mix(in srgb, var(--sunk) 45%, transparent); transition: border-color 200ms, box-shadow 200ms; }
.insp-part .label { margin: 0 0 4px; }
.insp-part .label span { color: var(--faint); text-transform: none; letter-spacing: 0; margin-left: 6px; }
.inspector pre { font-family: var(--mono); font-size: 12.5px; line-height: 1.6; margin: 0; white-space: pre-wrap; word-break: break-word; }
.inspector pre .k { color: var(--pay); } .inspector pre .s { color: var(--ink); } .inspector pre .n { color: var(--hdr); } .inspector pre .c { color: var(--faint); }
.inspector pre .secret { color: var(--sig); }
.inspector .valid { margin: 4px 0 0; font-family: var(--mono); font-size: 12px; line-height: 1.6; color: var(--sig); }
.inspector .valid.warn { color: var(--hdr); }
/* Hover a part on one side and the same part lights up on the other */
.panel[data-hot="hdr"] .p1, .panel[data-hot="pay"] .p2, .panel[data-hot="sig"] .p3 { background: color-mix(in srgb, currentColor 16%, transparent); border-radius: 3px; }
.panel[data-hot="hdr"] [data-part="hdr"] { border-color: color-mix(in srgb, var(--hdr) 55%, var(--line)); box-shadow: 0 0 0 1px color-mix(in srgb, var(--hdr) 25%, transparent); }
.panel[data-hot="pay"] [data-part="pay"] { border-color: color-mix(in srgb, var(--pay) 55%, var(--line)); box-shadow: 0 0 0 1px color-mix(in srgb, var(--pay) 25%, transparent); }
.panel[data-hot="sig"] [data-part="sig"] { border-color: color-mix(in srgb, var(--sig) 55%, var(--line)); box-shadow: 0 0 0 1px color-mix(in srgb, var(--sig) 25%, transparent); }

footer.site { padding-block: 28px calc(28px + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--line); }
footer.site .wrap { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; font-family: var(--mono); font-size: 12px; color: var(--faint); }

/* Reveal on scroll: script.js adds .reveal, then .in once the element is on screen. */
.reveal { opacity: 0; transform: translateY(18px); filter: blur(4px); transition: opacity 700ms var(--ease), transform 700ms var(--ease), filter 700ms var(--ease); }
.reveal.in { opacity: 1; transform: none; filter: none; }

/* GSAP entrances (script.js). CSS transitions pause while GSAP drives an element, or they'd smear it. */
.gs, .gs * { transition: none !important; }
/* Keep the gate hidden until its entrance has set the start state, so it doesn't flash in twice. Shown regardless after 2.5s. */
.motion-pending #gate .gate-grid { opacity: 0; animation: unhide 0s 2.5s forwards; }
@keyframes unhide { to { opacity: 1; } }

/* Gate ⇄ app swap (View Transitions, where supported). */
::view-transition-old(root) { animation: 260ms ease-in both vt-out; }
::view-transition-new(root) { animation: 520ms var(--ease) both vt-in; }
@keyframes vt-out { to { opacity: 0; transform: scale(.985); } }
@keyframes vt-in { from { opacity: 0; transform: scale(1.015); filter: blur(6px); } }


/* ── Glass ───────────────────────────────────────────────────────
   Frosted, translucent surfaces with a bright top edge, in the style of iOS.
   Floating chrome blurs what is behind it; content cards stay translucent without blur, which keeps scrolling cheap. */
.bar { background: var(--glass-bar); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); border-bottom-color: var(--glass-line); box-shadow: inset 0 1px 0 rgb(255 255 255 / .05), inset 0 -1px 0 rgb(255 255 255 / .06), 0 12px 32px -24px rgb(0 0 0 / .7); }
.card, .pill, .inspector > button, .inspector .panel {
  background: var(--glass-fill); border: 1px solid var(--glass-line); box-shadow: var(--glass-hl), var(--glass-drop);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); }
/* The sign-in card catches a moving highlight as the 401 tilts. */
#consent { background: radial-gradient(520px circle at var(--glare, 50%) -30%, rgb(255 255 255 / .12), transparent 45%), var(--glass-fill); border-radius: var(--r-panel); }
.res, .scope-card, .post, .audit, .claims, .idcard, .matrix-wrap, .filters button, .links a, .btn:not(.primary), .scope {
  background: var(--glass-fill); border-color: var(--glass-line); box-shadow: var(--glass-hl); }
.scope-card.ai { background: linear-gradient(160deg, color-mix(in srgb, var(--pay) 14%, transparent), transparent 60%), var(--glass-fill); border-color: color-mix(in srgb, var(--pay) 40%, var(--glass-line)); }
.scope.fixed { background: color-mix(in srgb, var(--sunk) 55%, transparent); }
.scope:has(input:checked) { background: linear-gradient(155deg, color-mix(in srgb, var(--pay) 12%, transparent), transparent 70%), var(--glass-fill); }
.filters { background: var(--glass-bar); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); }
.filters button[aria-pressed="true"] { background: linear-gradient(155deg, color-mix(in srgb, var(--pay) 18%, transparent), transparent), var(--glass-fill); }
.mailbox, .jwt { background: color-mix(in srgb, var(--sunk) 60%, transparent); box-shadow: inset 0 1px 2px rgb(0 0 0 / .12); }
.seg { background: linear-gradient(155deg, color-mix(in srgb, var(--c) 12%, transparent), transparent 60%), var(--glass-fill); box-shadow: var(--glass-hl), 0 26px 40px -24px color-mix(in srgb, var(--c) 65%, transparent); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); }
/* Primary buttons: tinted glass with a lit top edge and a soft glow. */
.btn.primary { background: linear-gradient(180deg, color-mix(in srgb, var(--sig) 82%, #fff), var(--sig) 55%); border-color: color-mix(in srgb, var(--sig) 70%, #fff);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .55), inset 0 -2px 6px rgb(0 0 0 / .12), 0 12px 28px -12px color-mix(in srgb, var(--sig) 80%, transparent); }
.btn.primary:hover { filter: brightness(1.05) saturate(1.1); }
.res:hover, .post:hover { box-shadow: var(--glass-hl), 0 24px 48px -30px rgb(0 0 0 / .5); }
.card, .res, .scope-card, .post, .audit, .claims, .idcard, .token-card { border-radius: var(--r-card); }
/* Floating panels get a luminous edge, brightest top-left, the way light catches thick glass. */
#consent, .inspector .panel { position: relative; }
#consent::before, .inspector .panel::before { content: ''; position: absolute; inset: -1px; border-radius: inherit; padding: 1px; pointer-events: none;
  background: linear-gradient(150deg, rgb(255 255 255 / .5), rgb(255 255 255 / .1) 26%, rgb(255 255 255 / .02) 58%, rgb(255 255 255 / .22));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; }
:root[data-theme="light"] #consent::before, :root[data-theme="light"] .inspector .panel::before { display: none; }
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .card, .pill, .inspector > button, .inspector .panel { background: var(--panel); }
  .bar, .filters { background: color-mix(in srgb, var(--bg) 92%, transparent); }
}

/* Signed in, the header pill shows just the timer ("token valid" is on the floating token button), so the header fits
   its column. Below 1260px the section capsule goes too, as on phones. */
#pill-text .hide-sm { display: none; }
@media (max-width: 1260px) { .nav .nav-group { display: none; } }
@media (max-width: 1080px) and (min-width: 861px) {
  .live-grid, .scope-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 860px) {
  .gate-grid, .about, .elevate { grid-template-columns: 1fr; }
  .resources, .live-grid, .scope-grid { grid-template-columns: 1fr; }
  .audit a { grid-template-columns: 1fr auto; gap: 4px 12px; }
  .audit time, .audit .cat { grid-column: 1; }
  .audit .go { grid-row: 1 / span 3; grid-column: 2; align-self: center; }
  .locked { grid-template-columns: auto minmax(0, 1fr); }
  .locked .btn { grid-column: 1 / -1; }
  .hide-sm { display: none; }
  .nav .nav-group { display: none; }
  /* Phones: Timeline and Blogs get their own row under the brand and session. */
  .bar-inner { flex-wrap: wrap; height: auto; padding-block: 10px; row-gap: 10px; }
  .nav { order: 3; width: 100%; gap: 8px; }
  .nav .nav-out { flex: 1; margin-left: 0; text-align: center; padding: 8px 10px; }
  .bar-inner { gap: 10px; }
  .session { gap: 8px; }
  .filters { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin-inline: calc(-1 * var(--gutter)); padding-inline: var(--gutter); }
  .filters button { flex: none; }
  .log { font-size: 12px; }
  /* Phones: the card comes straight after the intro, so Enter as guest is on the first screen; the request log follows it. */
  .gate-grid { row-gap: 0; }
  .gate-grid > :first-child { display: contents; }
  .gate .lede { margin-bottom: 20px; }
  .gate-side { margin-bottom: 28px; }
  .log { order: 1; }
  .gate { padding-block: 12px 64px; }
  .code3d { font-size: 72px; padding-block: 4px 14px; }
  .gate h1 { margin: 12px 0 10px; }
  .avatar { width: 44px; height: 44px; }
  .idp-head { padding-bottom: 12px; }
  .demo-chip { margin-bottom: 12px; }
  .consent-q { margin-top: 12px; }
  /* The count doesn't fit beside "(optional)" on a phone; the arrow alone shows it opens. */
  .scope-sum { display: none; }
  .scope-picker > summary::after { content: '▾'; font-family: var(--mono); font-size: 12px; color: var(--pay); }
  .scope-picker[open] > summary::after { content: '▴'; }
  .claims { font-size: 13px; line-height: 1.85; }
  .inspector { right: 16px; }
  .inspector .panel { width: calc(100vw - 32px); max-height: 70vh; padding: 16px; }
  .insp-grid { grid-template-columns: 1fr; }
  .insp-top { flex-wrap: wrap; }
  footer.site { padding-bottom: calc(76px + env(safe-area-inset-bottom, 0px)); }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; filter: none; transition: none; }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
  .backdrop::before, .forge.in .forge-plane, .token-card:not([hidden]), #consent.leaving, .mint-status .led { animation: none; }
  .code3d-tilt, .forge-plane { transform: none; }
  .res, .btn { transition: none; }
}

/* Theme switch: a sun in dark mode (go light), a moon in light mode (go dark) */
.theme-btn { display: inline-grid; place-items: center; width: 32px; height: 32px; padding: 0; border-radius: 50%; color: var(--muted);
  background: var(--glass-fill); border: 1px solid var(--glass-line); box-shadow: var(--glass-hl); transition: color 160ms, border-color 160ms, transform 300ms var(--ease); }
.theme-btn:hover { color: var(--ink); border-color: color-mix(in srgb, var(--sig) 50%, var(--glass-line)); transform: rotate(-20deg); }
.theme-btn .i-moon, :root[data-theme="light"] .theme-btn .i-sun { display: none; }
:root[data-theme="light"] .theme-btn .i-moon { display: block; }

/* Glass control: a round button beside the theme switch, opening a small clear ↔ tinted slider (glass.js). */
/* The popover hangs from the right edge of the header's controls, so it stays on screen on phones. */
.session { position: relative; }
.glass-ctl { display: inline-flex; }
.glass-btn { display: inline-grid; place-items: center; width: 32px; height: 32px; padding: 0; border-radius: 50%; color: var(--muted);
  background: var(--glass-fill); border: 1px solid var(--glass-line); box-shadow: var(--glass-hl); transition: color 160ms, border-color 160ms; }
.glass-btn:hover, .glass-btn[aria-expanded="true"] { color: var(--ink); border-color: color-mix(in srgb, var(--sig) 50%, var(--glass-line)); }
.glass-pop { position: absolute; right: 0; top: calc(100% + 10px); z-index: 50; width: 220px; padding: 14px 16px 12px; border-radius: var(--r-card);
  font-family: var(--mono); font-size: 12px; color: var(--muted); border: 1px solid var(--glass-line); box-shadow: var(--glass-hl), var(--glass-drop);
  /* Its own fill, not the adjustable one, so the control stays readable at the clear end. */
  background: linear-gradient(135deg, rgb(255 255 255 / .1), transparent 40%), color-mix(in srgb, var(--panel) 92%, transparent);
  -webkit-backdrop-filter: blur(24px) saturate(190%); backdrop-filter: blur(24px) saturate(190%); }
.glass-pop label { display: block; margin-bottom: 8px; color: var(--ink); }
.glass-pop input { display: block; width: 100%; margin: 0; accent-color: var(--sig); cursor: pointer; }
.glass-ends { display: flex; justify-content: space-between; margin-top: 6px; font-size: 11px; color: var(--faint); }
/* Light mode has no glass (see Layout rules), so there's nothing to adjust. */
:root[data-theme="light"] .glass-ctl { display: none; }

/* openid: always granted, so its box is ticked and can't be changed */
.scope.fixed { cursor: default; }
.scope.fixed input:disabled { opacity: .55; cursor: not-allowed; }

/* Authorize: a slow glow and a sheen across it until it's hovered or focused, so it reads as the next step */
#authorize { position: relative; overflow: hidden; isolation: isolate; animation: auth-glow 2.6s ease-in-out infinite; }
#authorize::after { content: ''; position: absolute; inset: 0; z-index: -1; background: linear-gradient(110deg, transparent 30%, rgb(255 255 255 / .45) 48%, transparent 66%);
  transform: translateX(-120%); animation: auth-sheen 3.2s ease-in-out 1s infinite; pointer-events: none; }
#authorize:hover, #authorize:focus-visible { animation: none; }
#authorize:hover::after, #authorize:focus-visible::after { animation: none; opacity: 0; }
@keyframes auth-glow {
  0%, 100% { box-shadow: inset 0 1px 0 rgb(255 255 255 / .55), inset 0 -2px 6px rgb(0 0 0 / .12), 0 12px 28px -12px color-mix(in srgb, var(--sig) 80%, transparent), 0 0 0 0 color-mix(in srgb, var(--sig) 45%, transparent); }
  50% { box-shadow: inset 0 1px 0 rgb(255 255 255 / .55), inset 0 -2px 6px rgb(0 0 0 / .12), 0 14px 34px -10px color-mix(in srgb, var(--sig) 90%, transparent), 0 0 0 7px color-mix(in srgb, var(--sig) 0%, transparent); }
}
@keyframes auth-sheen { 0% { transform: translateX(-120%); } 45%, 100% { transform: translateX(120%); } }
@media (prefers-reduced-motion: reduce) { #authorize, #authorize::after { animation: none; } }
