/* ==========================================================================
   KSE LABS — Editorial Stylesheet
   A warm-paper, magazine-grade design system.
   Square geometry, hairline rules, high-contrast serif display.
   ========================================================================== */

/* ==========================================================================
   0. TRIAL — Anthropic type stack
   ==========================================================================
   Anthropic Sans / Serif / Mono Web are Anthropic's commissioned corporate
   typefaces (designer "BSPK x Geist x Anthropic", vendor BSPK LLC). They
   carry no third-party licence and must not be deployed on kselabs.com.

   NOTE: the files are named KSELABS*.woff2 but are byte-identical copies of
   Anthropic's originals — the internal name table still reads "Anthropic
   Sans/Serif/Mono Web". Renaming the file does not change the font or its
   ownership. Family names below are kept honest on purpose.

   Enable by putting data-fonts="anthropic" on <html>; remove the attribute
   to fall back to the shippable Fraunces / Public Sans / JetBrains Mono.
   Delete this whole block plus the [data-fonts] rule to remove entirely.

   All three are variable: wght 300..800. Sans and Serif also carry
   opsz 16..48 (note: far narrower than Fraunces' 9..144).
   ========================================================================== */

@font-face {
    font-family: 'Anthropic Sans Web';
    src: url('assets/fonts/KSELABSSans_Roman.woff2') format('woff2');
    font-weight: 300 800;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Anthropic Sans Web';
    src: url('assets/fonts/KSELABSSans_Italic.woff2') format('woff2');
    font-weight: 300 800;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: 'Anthropic Serif Web';
    src: url('assets/fonts/KSELABSSerif_Roman.woff2') format('woff2');
    font-weight: 300 800;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Anthropic Serif Web';
    src: url('assets/fonts/KSELABSSerif_Italic.woff2') format('woff2');
    font-weight: 300 800;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: 'Anthropic Mono Web';
    src: url('assets/fonts/KSELABSMono_Roman.woff2') format('woff2');
    font-weight: 300 800;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Anthropic Mono Web';
    src: url('assets/fonts/KSELABSMono_Italic.woff2') format('woff2');
    font-weight: 300 800;
    font-style: italic;
    font-display: swap;
}

html[data-fonts="anthropic"] {
    --font-display: 'Anthropic Serif Web', Georgia, 'Times New Roman', serif;
    --font-body:    'Anthropic Sans Web', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif;
    --font-mono:    'Anthropic Mono Web', ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* The pinned opsz values below are calibrated to Fraunces' 9..144 axis and are
   meaningless on Anthropic Serif's 16..48 axis (66 would simply clamp to 48).
   Release them so the trial face uses its own automatic optical sizing. */
html[data-fonts="anthropic"] .display-1,
html[data-fonts="anthropic"] .display-2 { font-variation-settings: normal; }

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
    /* Paper & ink */
    --paper:       #F5F1EA;
    --paper-deep:  #EBE5D9;
    --surface:     #FBF9F5;
    --ink:         #1F1B16;
    --ink-soft:    #4B4239;
    --ink-mute:    #7C7266;

    /* Accent — burnt terracotta. 5.16:1 against --paper, so the 11px mono
       eyebrows and folios clear WCAG AA (the original #B5502F did not). */
    --clay:        #A8481F;
    --forest:      #2C3B35;
    --navy:        #26364A;

    /* Hairlines */
    --rule:        #DCD5C8;
    --rule-soft:   #E8E2D7;

    /* Type */
    --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
    --font-body:    'Public Sans', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif;
    --font-mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

    /* Motion */
    --ease:    cubic-bezier(.16, 1, .3, 1);
    --ease-io: cubic-bezier(.65, 0, .35, 1);

    /* Metrics */
    --gutter:    clamp(20px, 4vw, 64px);
    --max:       1340px;
    --measure:   49.5rem;   /* long-form reading column, ~75 characters */
    --section-y: clamp(76px, 10vw, 152px);
    --nav-h:     78px;
}

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

html {
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--nav-h) + 16px);
    -webkit-text-size-adjust: 100%;
}

body {
    background: var(--paper);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 17px;
    font-weight: 400;
    line-height: 1.65;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    font-feature-settings: "kern" 1, "liga" 1;
}

a { color: inherit; text-decoration: none; }
img, svg { max-width: 100%; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }

::selection { background: var(--clay); color: #FFF8F2; }

/* Paper grain — the single most important texture cue. */
.grain {
    position: fixed;
    inset: -50%;
    z-index: 2;
    pointer-events: none;
    opacity: .5;
    mix-blend-mode: multiply;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
}

/* --------------------------------------------------------------------------
   2. Inverted colour contexts
   -------------------------------------------------------------------------- */

.invert {
    --paper:      #1C1813;
    --paper-deep: #14110D;
    --surface:    #262019;
    --ink:        #F1EBE1;
    --ink-soft:   #BDB2A3;
    --ink-mute:   #8C8175;
    /* The accent is too dark to sit on this ground (3.04:1), so it is lifted
       while holding hue at 16° to stay terracotta.
       5.39:1 — clears AA for the 11px mono labels. */
    --clay:       #D9714B;
    --rule:       #3B332A;
    --rule-soft:  #2C251E;
    background: var(--paper);
    color: var(--ink);
}

.band-clay {
    --paper:      #A8481F;
    --paper-deep: #95401B;
    --surface:    #8F3E1A;
    --ink:        #FDF6EF;
    --ink-soft:   #F2DCCF;
    --ink-mute:   #E3BFA9;
    --clay:       #FDF6EF;
    --rule:       rgba(253, 246, 239, .3);
    --rule-soft:  rgba(253, 246, 239, .16);
    background: var(--paper);
    color: var(--ink);
}

/* --------------------------------------------------------------------------
   3. Layout primitives
   -------------------------------------------------------------------------- */

.wrap {
    width: 100%;
    max-width: var(--max);
    margin: 0 auto;
    padding: 0 var(--gutter);
}

.wrap-narrow { max-width: 940px; }

.section { padding: var(--section-y) 0; position: relative; }
.section--tight { padding: clamp(52px, 6vw, 92px) 0; }

.rule {
    height: 1px;
    width: 100%;
    background: var(--rule);
    transform-origin: left center;
}

.rule--ink { background: var(--ink); opacity: .85; }

/* Section heading block: folio column + title column */
.head {
    display: grid;
    grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
    gap: clamp(20px, 4vw, 72px);
    align-items: start;
    padding-top: clamp(20px, 2.5vw, 34px);
}

.head-folio {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .22em;
    text-transform: uppercase;
    color: var(--clay);
    padding-top: .9em;
    line-height: 1.9;
}

.head-folio span { display: block; color: var(--ink-mute); }

.head-body { max-width: 40ch; }
.head-body--wide { max-width: 62ch; }

.eyebrow {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .22em;
    text-transform: uppercase;
    color: var(--clay);
}

/* --------------------------------------------------------------------------
   4. Typography
   -------------------------------------------------------------------------- */

.display-1, .display-2, .display-3, .display-4 {
    font-family: var(--font-display);
    font-weight: 500;
    letter-spacing: -.02em;
    text-wrap: balance;
}

/* Fraunces' opsz axis changes the design, not just the size: low values give a
   sturdy, low-contrast cut, high values a thin Didone one. Automatic optical
   sizing ties opsz to font-size, so at our display scale it would silently
   select a much thinner cut than the reference. opsz is therefore pinned to
   the reference's values (hero 66, section titles ~40) and decoupled from
   size. Everything below display scale is left on auto, where it already
   lands in the right range. */
.display-1 {
    font-size: clamp(40px, 5.8vw, 84px);
    line-height: 1.04;
    letter-spacing: -.016em;
    font-variation-settings: "opsz" 66;
}

.display-2 {
    font-size: clamp(34px, 5.2vw, 68px);
    line-height: 1.02;
    letter-spacing: -.028em;
    font-variation-settings: "opsz" 42;
}

.display-3 {
    font-size: clamp(25px, 3.1vw, 40px);
    line-height: 1.12;
    letter-spacing: -.02em;
}

.display-4 {
    font-size: clamp(20px, 2.1vw, 27px);
    line-height: 1.2;
    letter-spacing: -.015em;
}

/* A plain, well-cut italic — not a swash. */
.accent {
    color: var(--clay);
    font-style: italic;
}

.lede {
    font-size: clamp(17px, 1.35vw, 20px);
    line-height: 1.62;
    color: var(--ink-soft);
    max-width: 58ch;
}

.body-text {
    color: var(--ink-soft);
    max-width: 66ch;
}

.body-text + .body-text { margin-top: 1.15em; }
.body-text strong { color: var(--ink); font-weight: 600; }

.body-text a {
    color: var(--clay);
    background-image: linear-gradient(var(--clay), var(--clay));
    background-size: 100% 1px;
    background-position: 0 100%;
    background-repeat: no-repeat;
    transition: background-size .5s var(--ease);
}
.body-text a:hover { background-size: 0 1px; }

.dropcap::first-letter {
    font-family: var(--font-display);
    font-size: 4.05em;
    line-height: .82;
    float: left;
    padding: .06em .12em 0 0;
    color: var(--clay);
}

.meta {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 400;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--ink-mute);
}

/* --------------------------------------------------------------------------
   5. Reveal animations
   -------------------------------------------------------------------------- */

/* The pre-animation (hidden) state is applied only once JS has confirmed it is
   running — see the guard script in <head>. If editorial.js fails to load or
   throws, the guard times out, `.js-reveal` is dropped, and every element
   renders normally instead of being stranded at opacity 0. */

.js-reveal [data-reveal] {
    opacity: 0;
    transform: translate3d(0, 26px, 0);
    transition:
        opacity 1.05s var(--ease) var(--d, 0s),
        transform 1.05s var(--ease) var(--d, 0s);
    will-change: opacity, transform;
}

.js-reveal [data-reveal].in { opacity: 1; transform: none; }

.js-reveal [data-reveal="rule"] {
    opacity: 1;
    transform: scaleX(0);
    transition: transform 1.15s var(--ease) var(--d, 0s);
}
.js-reveal [data-reveal="rule"].in { transform: scaleX(1); }

.js-reveal [data-reveal="plate"] {
    opacity: 1;
    transform: none;
    clip-path: inset(0 0 100% 0);
    transition: clip-path 1.25s var(--ease) var(--d, 0s);
}
.js-reveal [data-reveal="plate"].in { clip-path: inset(0 0 0 0); }
.js-reveal [data-reveal="plate"] img { transform: scale(1.12); transition: transform 1.6s var(--ease) var(--d, 0s); }
.js-reveal [data-reveal="plate"].in img { transform: scale(1); }

/* Line-by-line masked reveal for display headings */
.mask-line { display: block; overflow: hidden; padding-bottom: .04em; }
.mask-line > span { display: block; }

.js-reveal .mask-line > span {
    transform: translate3d(0, 105%, 0);
    transition: transform 1.15s var(--ease) var(--d, 0s);
    will-change: transform;
}
.js-reveal .mask-line.in > span { transform: none; }

/* --------------------------------------------------------------------------
   6. Reading progress + custom cursor
   -------------------------------------------------------------------------- */

.progress {
    position: fixed;
    top: 0; left: 0;
    height: 2px;
    width: 100%;
    background: var(--clay);
    transform: scaleX(0);
    transform-origin: left center;
    z-index: 120;
    pointer-events: none;
}

.cursor-dot, .cursor-ring {
    position: fixed;
    top: 0; left: 0;
    pointer-events: none;
    z-index: 200;
    border-radius: 50%;
    opacity: 0;
    transition: opacity .4s ease;
    mix-blend-mode: multiply;
}

.cursor-dot {
    width: 6px; height: 6px;
    margin: -3px 0 0 -3px;
    background: var(--clay);
}

.cursor-ring {
    width: 34px; height: 34px;
    margin: -17px 0 0 -17px;
    border: 1px solid rgba(31, 27, 22, .38);
    transition: opacity .4s ease, width .45s var(--ease), height .45s var(--ease),
                margin .45s var(--ease), border-color .45s var(--ease), background-color .45s var(--ease);
}

.cursor-on .cursor-dot, .cursor-on .cursor-ring { opacity: 1; }

.cursor-hot .cursor-ring {
    width: 62px; height: 62px;
    margin: -31px 0 0 -31px;
    border-color: rgba(181, 80, 47, .55);
    background: rgba(181, 80, 47, .07);
}
.cursor-hot .cursor-dot { opacity: 0; }

@media (hover: none), (pointer: coarse) {
    .cursor-dot, .cursor-ring { display: none; }
}

/* --------------------------------------------------------------------------
   7. Masthead
   -------------------------------------------------------------------------- */

.masthead {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 100;
    background: rgba(245, 241, 234, 0);
    border-bottom: 1px solid transparent;
    transition: transform .6s var(--ease), background-color .5s ease, border-color .5s ease,
                backdrop-filter .5s ease;
}

.masthead.is-stuck {
    background: rgba(245, 241, 234, .88);
    -webkit-backdrop-filter: blur(14px) saturate(1.4);
    backdrop-filter: blur(14px) saturate(1.4);
    border-bottom-color: var(--rule);
}

.masthead.is-hidden { transform: translateY(-102%); }

.masthead-inner {
    height: var(--nav-h);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 28px;
}

.brand {
    display: flex;
    align-items: center;
    gap: 11px;
    flex-shrink: 0;
}

.brand-mark {
    width: 27px; height: 27px;
    transition: transform .7s var(--ease);
}
.brand:hover .brand-mark { transform: rotate(-12deg); }

.brand-word {
    font-family: var(--font-display);
    font-size: 19px;
    font-weight: 600;
    letter-spacing: .01em;
    line-height: 1;
}

.brand-tm {
    font-family: var(--font-mono);
    font-size: 8px;
    letter-spacing: .1em;
    vertical-align: super;
    color: var(--ink-mute);
}

.nav {
    display: flex;
    align-items: center;
    gap: clamp(14px, 1.8vw, 30px);
    list-style: none;
    margin-left: auto;
}

.nav a {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 400;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--ink-soft);
    position: relative;
    padding: 4px 0;
    transition: color .35s ease;
}

.nav a::after {
    content: '';
    position: absolute;
    left: 0; bottom: 0;
    width: 100%; height: 1px;
    background: var(--clay);
    transform: scaleX(0);
    transform-origin: right center;
    transition: transform .5s var(--ease);
}

.nav a:hover { color: var(--clay); }
.nav a:hover::after { transform: scaleX(1); transform-origin: left center; }

.nav-cta { flex-shrink: 0; }

.menu-toggle {
    display: none;
    width: 44px; height: 44px;
    background: none;
    border: 1px solid var(--rule);
    cursor: pointer;
    position: relative;
    flex-shrink: 0;
}

.menu-toggle span {
    position: absolute;
    left: 12px;
    width: 20px; height: 1px;
    background: var(--ink);
    transition: transform .5s var(--ease), opacity .3s ease;
}
.menu-toggle span:nth-child(1) { top: 17px; }
.menu-toggle span:nth-child(2) { top: 22px; }
.menu-toggle span:nth-child(3) { top: 27px; }

.menu-toggle.open span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.menu-toggle.open span:nth-child(2) { opacity: 0; }
.menu-toggle.open span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

/* Mobile drawer */
.drawer {
    position: fixed;
    inset: 0;
    z-index: 99;
    background: var(--paper);
    padding: calc(var(--nav-h) + 28px) var(--gutter) 40px;
    display: flex;
    flex-direction: column;
    clip-path: inset(0 0 100% 0);
    transition: clip-path .8s var(--ease);
    overflow-y: auto;
}

.drawer.open { clip-path: inset(0 0 0 0); }

.drawer-list { list-style: none; }

.drawer-list li { border-bottom: 1px solid var(--rule); }

.drawer-list a {
    display: flex;
    align-items: baseline;
    gap: 14px;
    padding: 18px 2px;
    font-family: var(--font-display);
    font-size: 30px;
    letter-spacing: -.02em;
    opacity: 0;
    transform: translateY(18px);
    transition: opacity .7s var(--ease), transform .7s var(--ease);
}

.drawer.open .drawer-list a { opacity: 1; transform: none; }

.drawer-list .n {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .2em;
    color: var(--clay);
}

.drawer-foot { margin-top: auto; padding-top: 34px; }

/* --------------------------------------------------------------------------
   8. Buttons
   -------------------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    font-weight: 500;
    letter-spacing: .17em;
    text-transform: uppercase;
    line-height: 1;
    padding: 17px 28px;
    border: 1px solid var(--ink);
    border-radius: 0;
    background: transparent;
    color: var(--ink);
    cursor: pointer;
    position: relative;
    isolation: isolate;
    overflow: hidden;
    white-space: nowrap;
    transition: color .55s var(--ease), border-color .55s var(--ease);
}

.btn::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--ink);
    transform: scaleY(0);
    transform-origin: center bottom;
    transition: transform .6s var(--ease);
}

.btn:hover::before { transform: scaleY(1); }
.btn:hover { color: var(--paper); }

.btn svg { transition: transform .55s var(--ease); flex-shrink: 0; }
.btn:hover svg { transform: translateX(5px); }

.btn-solid {
    background: var(--ink);
    color: var(--paper);
    border-color: var(--ink);
}
.btn-solid::before { background: var(--clay); }
.btn-solid:hover { color: #FFF7F1; border-color: var(--clay); }

.btn-clay {
    background: var(--clay);
    color: #FFF7F1;
    border-color: var(--clay);
}
.btn-clay::before { background: var(--ink); }
.btn-clay:hover { color: var(--paper); border-color: var(--ink); }

.btn-sm { padding: 13px 20px; font-size: 10.5px; letter-spacing: .15em; }
.btn-lg { padding: 21px 36px; font-size: 12px; }
.btn-full { width: 100%; }

/* Text link with sliding arrow */
.link {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .15em;
    text-transform: uppercase;
    color: var(--clay);
    padding-bottom: 3px;
    position: relative;
}

.link::after {
    content: '';
    position: absolute;
    left: 0; bottom: 0;
    width: 100%; height: 1px;
    background: currentColor;
    transform: scaleX(1);
    transform-origin: right center;
    transition: transform .55s var(--ease);
}
.link:hover::after { transform: scaleX(0); }
.link svg { transition: transform .55s var(--ease); }
.link:hover svg { transform: translateX(5px); }

/* --------------------------------------------------------------------------
   9. Hero — the cover
   -------------------------------------------------------------------------- */

.hero {
    padding-top: calc(var(--nav-h) + clamp(40px, 7vw, 92px));
    padding-bottom: clamp(40px, 5vw, 72px);
    position: relative;
    overflow: hidden;
}

.hero-folio {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 18px;
    margin-bottom: clamp(26px, 3.4vw, 46px);
}

.hero-folio .dot {
    width: 5px; height: 5px;
    background: var(--clay);
    flex-shrink: 0;
    animation: pulse 2.6s var(--ease-io) infinite;
}

@keyframes pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%      { opacity: .35; transform: scale(.7); }
}

.hero-title { margin-bottom: clamp(30px, 3.6vw, 52px); }

.hero-deck {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: clamp(28px, 4vw, 72px);
    align-items: start;
    padding-top: clamp(26px, 3vw, 42px);
}

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: clamp(26px, 3vw, 38px);
}

/* Rotating capability index */
.rotator-box { border-left: 1px solid var(--rule); padding-left: clamp(18px, 2.2vw, 30px); }

.rotator-label { margin-bottom: 14px; }

.rotator {
    position: relative;
    height: 1.28em;
    overflow: hidden;
    font-family: var(--font-display);
    font-size: clamp(23px, 2.5vw, 34px);
    line-height: 1.28;
    letter-spacing: -.015em;
}

.rotator i {
    position: absolute;
    inset: 0;
    font-style: italic;
    color: var(--clay);
    transform: translateY(105%);
    opacity: 0;
    transition: transform .85s var(--ease), opacity .5s ease;
    white-space: nowrap;
}

/* Without the motion layer, show the first word instead of an empty slot. */
html:not(.js-reveal) .rotator i:first-child { transform: none; opacity: 1; }

.rotator i.on  { transform: translateY(0);     opacity: 1; }
.rotator i.out { transform: translateY(-105%); opacity: 0; }

.rotator-note { margin-top: 16px; max-width: 30ch; font-size: 14px; color: var(--ink-mute); line-height: 1.6; }

/* Colophon stats */
.colophon {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    border-top: 1px solid var(--rule);
    margin-top: clamp(44px, 5.5vw, 84px);
}

.colophon-item {
    padding: clamp(22px, 2.6vw, 34px) clamp(14px, 2vw, 28px) 0 0;
    position: relative;
}

.colophon-item + .colophon-item {
    padding-left: clamp(18px, 2.4vw, 34px);
    border-left: 1px solid var(--rule);
}

.colophon-num {
    font-family: var(--font-display);
    font-size: clamp(42px, 5.2vw, 74px);
    line-height: 1;
    letter-spacing: -.04em;
    display: flex;
    align-items: baseline;
}

.colophon-num sup {
    font-family: var(--font-mono);
    font-size: .24em;
    letter-spacing: .04em;
    color: var(--clay);
    align-self: flex-start;
    margin: .55em 0 0 4px;
}

.colophon-label { margin-top: 12px; max-width: 16ch; line-height: 1.7; }

/* --------------------------------------------------------------------------
   10. Ticker
   -------------------------------------------------------------------------- */

.ticker {
    border-top: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
    padding: 15px 0;
    overflow: hidden;
    background: var(--surface);
}

.ticker-track {
    display: flex;
    width: max-content;
    animation: ticker 48s linear infinite;
}

.ticker:hover .ticker-track { animation-play-state: paused; }

.ticker-track span {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: .24em;
    text-transform: uppercase;
    color: var(--ink-soft);
    padding: 0 26px;
    white-space: nowrap;
}

.ticker-track .marquee-dot { color: var(--clay); padding: 0; font-size: 8px; }

@keyframes ticker {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-50%, 0, 0); }
}

/* --------------------------------------------------------------------------
   11. About
   -------------------------------------------------------------------------- */

.about-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    gap: clamp(34px, 5vw, 84px);
    align-items: start;
    margin-top: clamp(34px, 4vw, 58px);
}

.about-copy { column-gap: 44px; }

.tenets { border-top: 1px solid var(--ink); }

.tenet {
    padding: clamp(20px, 2.4vw, 30px) 0;
    border-bottom: 1px solid var(--rule);
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr);
    gap: 16px;
    align-items: start;
    transition: padding-left .6s var(--ease);
}

.tenet:hover { padding-left: 10px; }

.tenet-icon { color: var(--clay); padding-top: 3px; }
.tenet-icon svg { width: 22px; height: 22px; }

.tenet h3 {
    font-family: var(--font-display);
    font-size: 21px;
    font-weight: 500;
    letter-spacing: -.015em;
    margin-bottom: 5px;
}

.tenet p { font-size: 14.5px; line-height: 1.6; color: var(--ink-mute); }

/* Pull quote */
.pullquote {
    margin-top: clamp(36px, 4vw, 56px);
    padding: clamp(28px, 3.4vw, 46px) 0;
    border-top: 1px solid var(--ink);
    border-bottom: 1px solid var(--ink);
    text-align: center;
}

.pullquote p {
    font-family: var(--font-display);
    font-size: clamp(22px, 3vw, 38px);
    line-height: 1.24;
    letter-spacing: -.024em;
    font-style: italic;
    max-width: 22ch;
    margin: 0 auto;
    text-wrap: balance;
}

.pullquote cite { display: block; margin-top: 18px; font-style: normal; }

/* --------------------------------------------------------------------------
   12. Services — the index
   -------------------------------------------------------------------------- */

.index { margin-top: clamp(34px, 4vw, 58px); border-bottom: 1px solid var(--rule); }

.index-row {
    display: grid;
    grid-template-columns: 62px minmax(0, 1fr) minmax(0, 1.25fr);
    gap: clamp(14px, 2.6vw, 44px);
    align-items: start;
    padding: clamp(24px, 2.9vw, 38px) clamp(10px, 1.6vw, 24px);
    border-top: 1px solid var(--rule);
    position: relative;
    isolation: isolate;
    transition: color .6s var(--ease), padding-left .6s var(--ease);
}

.index-row::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--ink);
    transform: scaleY(0);
    transform-origin: center bottom;
    transition: transform .62s var(--ease);
}

.index-row:hover::before { transform: scaleY(1); }
.index-row:hover { color: var(--paper); padding-left: clamp(22px, 2.6vw, 40px); }

.index-num {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: .14em;
    color: var(--clay);
    padding-top: .55em;
    transition: color .5s var(--ease);
}
.index-row:hover .index-num { color: var(--clay); }

.index-title {
    font-family: var(--font-display);
    font-size: clamp(21px, 2.15vw, 30px);
    font-weight: 500;
    line-height: 1.14;
    letter-spacing: -.022em;
}

.index-body { display: flex; flex-direction: column; gap: 12px; }

.index-desc {
    font-size: 15px;
    line-height: 1.6;
    color: var(--ink-mute);
    max-width: 56ch;
    transition: color .5s var(--ease);
}
.index-row:hover .index-desc { color: rgba(245, 241, 234, .74); }

.index-tags {
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--ink-mute);
    transition: color .5s var(--ease);
}
.index-row:hover .index-tags { color: rgba(245, 241, 234, .5); }

/* --------------------------------------------------------------------------
   13. Work
   -------------------------------------------------------------------------- */

.plate {
    position: relative;
    display: block;
    overflow: hidden;
    background: var(--paper-deep);
    border: 1px solid var(--rule);
    width: 100%;
}

.plate img {
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: center;
    transition: transform 1.3s var(--ease);
}

/* Screenshots read from the top; photographs read from the middle. */
.plate--screen img,
.plate--site img { object-position: top center; }

.plate:hover img { transform: scale(1.045); }

.plate::after {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--ink);
    opacity: 0;
    transition: opacity .5s ease;
    pointer-events: none;
}
.plate:hover::after { opacity: .05; }

.plate--screen { aspect-ratio: 9 / 19.5; cursor: pointer; }
.plate--site   { aspect-ratio: 16 / 10; }
.plate--wide   { aspect-ratio: 4 / 3; }

.plate-cap {
    font-family: var(--font-mono);
    font-size: 9.5px;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--ink-mute);
    margin-top: 9px;
}

.plates {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(9px, 1.1vw, 16px);
}

/* Featured spread */
.spread {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.02fr);
    gap: clamp(30px, 4.4vw, 78px);
    align-items: center;
    margin-top: clamp(34px, 4vw, 58px);
    padding-bottom: clamp(44px, 5vw, 76px);
    border-bottom: 1px solid var(--ink);
}

/* Mirrored spread — plates lead, prose follows. Alternating the image side
   down a long portfolio stops nine consecutive entries reading as one
   repeating block. The plates column keeps the wider track. */
.spread--flip { grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr); }

/* On a single column the prose has to come first regardless of source order,
   or the reader meets three screenshots before learning what they are. */
@media (max-width: 900px) {
    .spread--flip > .plates { order: 2; }
    .spread--flip > div:not(.plates) { order: 1; }
}

/* Bridge from the featured pair to the full portfolio. */
.work-more {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 20px;
    padding: clamp(26px, 3vw, 40px) 0;
    border-bottom: 1px solid var(--rule);
}
.work-more .body-text { color: var(--ink-mute); max-width: 62ch; margin: 0; }

.entry-flag {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: #FFF7F1;
    background: var(--clay);
    padding: 6px 11px;
    margin-bottom: 20px;
}

.entry-flag--ink { background: var(--ink); }
.entry-flag--gold { background: var(--forest); }

.entry-kicker {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 14px;
    margin-bottom: 12px;
}

.entry-mark {
    width: 34px; height: 34px;
    border: 1px solid var(--rule);
    background: var(--surface);
    object-fit: contain;
    padding: 3px;
    flex-shrink: 0;
}

.entry-title {
    font-family: var(--font-display);
    font-size: clamp(28px, 3.4vw, 46px);
    font-weight: 500;
    line-height: 1.04;
    letter-spacing: -.03em;
    margin-bottom: 14px;
}

.entry-desc { color: var(--ink-soft); max-width: 54ch; line-height: 1.64; }
.entry-desc + .entry-desc { margin-top: .9em; }

.entry-note { font-size: 13px; color: var(--ink-mute); font-style: italic; margin-top: 10px; }

.entry-tags {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 22px;
}

.tag {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .15em;
    text-transform: uppercase;
    padding: 7px 12px;
    border: 1px solid var(--rule);
    color: var(--ink-mute);
    background: transparent;
}

a.tag {
    border-color: var(--ink);
    color: var(--ink);
    transition: background-color .45s var(--ease), color .45s var(--ease);
}
a.tag:hover { background: var(--ink); color: var(--paper); }

a.tag--clay { border-color: var(--clay); background: var(--clay); color: #FFF7F1; }
a.tag--clay:hover { background: var(--ink); border-color: var(--ink); }

.entry-foot { margin-top: 22px; }

.entry-specs {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1px;
    background: var(--rule);
    border: 1px solid var(--rule);
    margin-top: 26px;
}

.entry-spec { background: var(--paper); padding: 15px 17px; }
.entry-spec dt { font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .17em; text-transform: uppercase; color: var(--ink-mute); }
.entry-spec dd { font-size: 14.5px; font-weight: 500; margin-top: 5px; }

/* Two-up entry grid */
.entries {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1px;
    background: var(--rule);
    border-bottom: 1px solid var(--rule);
}

.entry {
    background: var(--paper);
    padding: clamp(26px, 3.2vw, 44px) clamp(20px, 2.6vw, 38px);
    display: flex;
    flex-direction: column;
    transition: background-color .55s var(--ease);
}

.entry:hover { background: var(--surface); }

/* Outer cells flush with the container so the grid aligns to the page margin */
.entries > .entry:nth-child(odd)  { padding-left: 0; }
.entries > .entry:nth-child(even) { padding-right: 0; }

.entry > .entry-flag { align-self: flex-start; }

.entry .plates { margin-top: auto; padding-top: clamp(22px, 2.6vw, 32px); }

/* Grid entries show a cropped detail; the lightbox has the full screen. */
.entry .plate--screen { aspect-ratio: 9 / 14; }

.entry-rating {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: .1em;
    color: var(--clay);
    margin-left: auto;
}

.entry-cat {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--ink-mute);
}

/* Websites sub-section */
.sub-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 24px;
    margin-top: clamp(56px, 7vw, 104px);
    padding-bottom: clamp(20px, 2.4vw, 30px);
    border-bottom: 1px solid var(--ink);
}

.sites {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(26px, 3.4vw, 56px);
    margin-top: clamp(28px, 3.4vw, 44px);
}

.site-info { margin-top: 20px; }
.site-info h4 {
    font-family: var(--font-display);
    font-size: clamp(21px, 2.1vw, 27px);
    font-weight: 500;
    letter-spacing: -.02em;
    line-height: 1.1;
    margin-bottom: 6px;
}
.site-info p { font-size: 15px; color: var(--ink-soft); margin-top: 10px; line-height: 1.6; max-width: 46ch; }

/* --------------------------------------------------------------------------
   14. Private demo widget
   -------------------------------------------------------------------------- */

.private-demo { margin-top: 26px; }

.private-demo-card {
    background: var(--surface);
    border: 1px solid var(--rule);
    padding: clamp(18px, 2.2vw, 26px);
    transition: opacity .38s ease;
}

.private-demo-card.pd-transitioning { opacity: .35; }

.pd-file-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .13em;
    text-transform: uppercase;
}

.pd-file-name { color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pd-file-status { color: var(--clay); flex-shrink: 0; }

.pd-divider { height: 1px; background: var(--rule); margin: 14px 0; }

.pd-redacted-lines { display: flex; flex-direction: column; gap: 7px; }
.pd-line-row { display: flex; gap: 7px; }
.pd-line { height: 7px; background: var(--paper-deep); }

.pd-answer {
    margin: 15px 0;
    padding: 15px 17px;
    background: var(--paper);
    border-left: 2px solid var(--clay);
}

.pd-answer-label {
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--clay);
    margin-bottom: 8px;
}

.pd-answer-text {
    font-family: var(--font-display);
    font-size: 16px;
    font-style: italic;
    line-height: 1.45;
}

.pd-cite {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 15px;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .1em;
    color: var(--ink-mute);
}
.pd-cite-arrow { color: var(--clay); }

.pd-input {
    display: flex;
    align-items: center;
    gap: 11px;
    margin-top: 15px;
    padding: 12px 14px;
    border: 1px solid var(--rule);
    background: var(--paper);
    font-family: var(--font-mono);
    font-size: 11px;
}

.pd-input-icon { color: var(--clay); }
.pd-input-text { flex: 1; color: var(--ink-soft); transition: opacity .38s ease; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pd-input-ask { color: var(--ink-mute); letter-spacing: .13em; flex-shrink: 0; }

/* --------------------------------------------------------------------------
   14b. Constellation (mindmap)
   Nodes drift on a CSS transform; connector lines are drawn once to each
   node's BASE position. Drift amplitude is deliberately smaller than the
   node radius, so a line always terminates inside its node and the lines
   never need redrawing per frame.
   -------------------------------------------------------------------------- */

/* Scroll choreography.
   --p is scroll progress through .mm-scroll (0..1), set by JS on the section.
   Phases: 0.00–0.55 the two title words travel from centred to their corners;
           0.45–0.90 the field (stage chrome, threads, nodes) assembles.
   Everything below degrades to the finished state if JS never runs, because
   the default value of --p is 1. */
/* The pinned pane supplies its own vertical rhythm. Leaving the usual section
   padding on would offset the sticky container and push the 100vh pane past
   the bottom of the viewport. */
.constellation { padding: 0; }

.mm-scroll {
    height: 230vh;
    position: relative;
}

.mm-pin {
    position: sticky;
    top: 0;
    height: 100vh;
    display: flex;
    align-items: center;
    overflow: hidden;
}

.mm-pin-inner { width: 100%; position: relative; }

/* Intro copy sits centred under the joined title, as one composition, and
   clears out as the words begin to separate. Absolutely positioned so it
   takes no layout space — in flow it pushed the pinned pane down and left
   the dead gap above the title. */
.mm-intro {
    position: absolute;
    left: 50%;
    top: 50%;
    width: min(560px, 82vw);
    margin-top: clamp(38px, 4.6vw, 62px);
    translate: -50% 0;
    text-align: center;
    opacity: var(--intro, 1);
    pointer-events: none;
    z-index: 9;
}

.mm-intro .head-folio { color: var(--clay); margin-bottom: 10px; }
.mm-intro .head-folio span { display: inline; color: var(--ink-mute); }
.mm-intro .head-folio span::before { content: ' — '; }
.mm-intro .lede { margin: 0 auto; max-width: 46ch; }

/* Scroll affordance — also a shortcut straight to the assembled field. */
.mm-scroll-cue {
    margin-top: clamp(20px, 2.4vw, 30px);
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 13px 22px;
    border: 1px solid var(--rule);
    background: transparent;
    color: var(--ink-soft);
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .17em;
    text-transform: uppercase;
    cursor: pointer;
    pointer-events: auto;
    transition: border-color .4s var(--ease), color .4s var(--ease), background-color .4s var(--ease);
}
.mm-scroll-cue:hover { border-color: var(--ink); color: var(--ink); background: var(--surface); }
.mm-scroll-cue svg { animation: mm-nudge 1.9s var(--ease-io) infinite; }

@keyframes mm-nudge {
    0%, 60%, 100% { translate: 0 0; opacity: .75; }
    30%           { translate: 0 4px; opacity: 1; }
}

.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.mm {
    position: relative;
    width: 100%;
    padding: 0 var(--gutter);
}

.mm-stage {
    position: relative;
    width: 100%;
    /* Constrain the WIDTH so the 16/9 ratio always holds. Capping max-height
       instead lets the box flatten (2.35:1 on a short laptop), which squashes
       every percentage position and pushes the top row out of frame. */
    max-width: min(1500px, calc(74vh * 16 / 9));
    margin: 0 auto;
    aspect-ratio: 16 / 9;
    overflow: hidden;
}

/* No frame, no panel — the field sits directly on the page background. */

.mm-lines {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    pointer-events: none;
}

.mm-lines line {
    stroke: var(--rule);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
    opacity: 0;
    transition: opacity .8s var(--ease), stroke .5s ease;
}
.mm.is-live .mm-lines line { opacity: .95; }
.mm-lines line.is-lit { stroke: var(--clay); opacity: 1; }

/* The two anchor words ARE the section heading, split across the canvas. */
.mm-title { margin: 0; }

.mm-word {
    position: absolute;
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(26px, 3.9vw, 60px);
    line-height: .98;
    letter-spacing: -.02em;
    color: var(--ink);
    white-space: nowrap;
    pointer-events: none;
    z-index: 8;
    /* JS supplies the centred-start offset in --dx/--dy; at --p:1 both are
       cancelled and the words rest in their corners. */
    translate: calc(var(--dx, 0px) * (1 - var(--p, 1)))
               calc(var(--dy, 0px) * (1 - var(--p, 1)));
    scale: calc(1 + (1 - var(--p, 1)) * var(--grow, .35));
}
.mm-word--a { left: clamp(14px, 2.6vw, 44px); top: clamp(14px, 2.2vw, 34px); }
.mm-word--b { right: clamp(14px, 2.6vw, 44px); bottom: clamp(14px, 2.2vw, 30px); }

/* The field: threads, clusters and nodes fade up together after the split.
   Opacity only — the drift keyframes own `translate`, so a static offset here
   would simply be overridden once the animation starts. */
.mm-lines,
.mm-cluster,
.mm-node { opacity: var(--assemble, 1); }

/* Cluster labels */
.mm-cluster {
    position: absolute;
    left: var(--x);
    top: var(--y);
    transform: translate(-50%, -50%);
    width: clamp(150px, 17vw, 232px);
    text-align: center;
    z-index: 3;
    pointer-events: none;
}

.mm-cluster h3 {
    font-family: var(--font-display);
    font-size: clamp(15px, 1.45vw, 21px);
    font-weight: 500;
    line-height: 1.16;
    letter-spacing: -.015em;
    margin-bottom: 6px;
}

.mm-cluster p {
    font-size: clamp(11px, .88vw, 13px);
    line-height: 1.5;
    color: var(--ink-mute);
}

/* Nodes */
.mm-node {
    position: absolute;
    left: var(--x);
    top: var(--y);
    width: var(--s);
    height: var(--s);
    margin: calc(var(--s) / -2) 0 0 calc(var(--s) / -2);
    z-index: 2;
    /* No frame: the reference lets the images sit bare on the paper, like
       cut-outs scattered on a desk. A hairline round each reads as a UI grid. */
    border: 0;
    background: transparent;
    overflow: hidden;
    animation: mm-drift var(--d, 20s) ease-in-out infinite;
    animation-delay: var(--dl, 0s);
    transition: box-shadow .45s var(--ease), z-index 0s;
    /* Not interactive until the field has actually arrived — otherwise an
       invisible node still fires its hover preview. */
    pointer-events: none;
}

/* The constellation zooms out into place as one unit, rather than each node
   scaling on its own — the whole field starts pushed in close and settles
   back. Zoom controls multiply into the same transform. */
.mm-field {
    position: absolute;
    /* Inset the coordinate space so a node at the extreme of its range still
       has room for its own half-width plus the drift amplitude. */
    inset: 6% 3%;
    transform-origin: center center;
    scale: calc(var(--zoom, 1) * (1 + (1 - var(--assemble, 1)) * .55));
    transition: scale .7s var(--ease);
}

.mm.is-ready .mm-node { pointer-events: auto; }

.mm-node img {
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: top center;
    transition: transform 1s var(--ease), filter .55s var(--ease);
}

/* Torch: the field is desaturated, and colour returns by proximity to the
   pointer rather than only on direct hover. --lit (0..1) is written per node
   by the motion layer. Hover-capable pointers only — on touch there is no
   pointer to carry the light, so the field stays in full colour. */
@media (hover: hover) and (pointer: fine) {
    .mm-node img {
        filter:
            grayscale(calc(1 - var(--lit, 0)))
            contrast(calc(.92 + var(--lit, 0) * .08))
            opacity(calc(.7 + var(--lit, 0) * .3));
        transition: filter .18s linear, transform 1s var(--ease);
    }
    .mm-node:hover img,
    .mm-node:focus-visible img { filter: none; }
}

/* Soft light that follows the cursor. Lives in the stage, not the field, so
   the entrance zoom and the zoom controls don't scale it. */
.mm-torch {
    position: absolute;
    left: 0; top: 0;
    width: 520px; height: 520px;
    margin: -260px 0 0 -260px;
    border-radius: 50%;
    pointer-events: none;
    z-index: 1;
    opacity: 0;
    transition: opacity .45s var(--ease);
    background: radial-gradient(circle closest-side,
        rgba(168, 72, 31, .13) 0%,
        rgba(168, 72, 31, .06) 38%,
        rgba(168, 72, 31, 0) 72%);
}

.mm.is-torch .mm-torch { opacity: 1; }

.mm-node--plate img { object-position: center; }
.mm-node--wide { height: calc(var(--s) * .64); margin-top: calc(var(--s) * -.32); }

.mm-node:hover,
.mm-node:focus-visible {
    box-shadow: 0 0 0 2px var(--clay), 0 0 0 6px rgba(168, 72, 31, .12);
    z-index: 6;
}
.mm-node:hover img { transform: scale(1.08); }

/* Translate only — the static `rotate` above survives untouched. */
@keyframes mm-drift {
    0%   { translate: 0 0; }
    28%  { translate: 6px -9px; }
    54%  { translate: -7px -5px; }
    78%  { translate: 4px 6px; }
    100% { translate: 0 0; }
}

/* Hover preview */
.mm-preview {
    position: absolute;
    z-index: 20;
    width: 210px;
    background: var(--paper);
    border: 1px solid var(--ink);
    padding: 8px;
    opacity: 0;
    transform: translateY(6px);
    transition: opacity .3s var(--ease), transform .3s var(--ease);
    pointer-events: none;
}
.mm-preview.is-on { opacity: 1; transform: none; }

.mm-preview-shot {
    width: 100%;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    background: var(--paper-deep);
    border: 1px solid var(--rule);
}
.mm-preview-shot img { width: 100%; height: 100%; object-fit: cover; object-position: top center; }

.mm-preview-meta { padding: 9px 2px 2px; }
.mm-preview-meta strong {
    display: block;
    font-family: var(--font-display);
    font-size: 16px;
    font-weight: 500;
    letter-spacing: -.015em;
    line-height: 1.15;
}
.mm-preview-meta .meta { font-size: 9.5px; margin-top: 4px; display: block; }

/* Bar */
.mm-bar {
    max-width: 1500px;
    margin: 16px auto 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.mm-zoom { display: flex; align-items: center; gap: 8px; }

.mm-zoom-btn {
    width: 34px; height: 34px;
    display: grid;
    place-items: center;
    border: 1px solid var(--rule);
    background: transparent;
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 15px;
    line-height: 1;
    cursor: pointer;
    transition: background-color .4s var(--ease), color .4s var(--ease), border-color .4s var(--ease);
}
.mm-zoom-btn:hover:not(:disabled) { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.mm-zoom-btn:disabled { opacity: .32; cursor: default; }

/* Mobile keeps the constellation rather than falling back to a grid — the
   stage just goes portrait and everything scales down with it. Nodes carry an
   optional --mx/--my for positions that need to move in the taller frame. */
@media (max-width: 900px) {
    /* The constellation is a landscape, hover-driven object: the portrait
       frame crams 25 nodes into a column, the preview-on-hover it is built
       around has no touch equivalent, and it costs ~230vh of scrolling to
       pass. Every case study it links to is reachable from Work and Services
       on this same page, so hiding it loses no route and no unique link.
       editorial.js reads offsetParent and skips its setup entirely. */
    .constellation { display: none; }

    .mm-scroll { height: 210vh; }
    .mm { padding: 0 clamp(12px, 3vw, 20px); }

    .mm-stage {
        aspect-ratio: 3 / 4.3;
        max-height: 74vh;
    }

    .mm-node {
        left: var(--mx, var(--x));
        top: var(--my, var(--y));
        width: calc(var(--s) * .58);
        height: calc(var(--s) * .58);
        margin: calc(var(--s) * -.29) 0 0 calc(var(--s) * -.29);
    }
    .mm-node--wide {
        height: calc(var(--s) * .37);
        margin-top: calc(var(--s) * -.185);
    }

    .mm-cluster {
        left: var(--mx, var(--x));
        top: var(--my, var(--y));
        width: min(64vw, 250px);
    }
    .mm-cluster h3 { font-size: 15px; }
    /* The descriptions don't survive the portrait frame — the questions carry
       it, and the detail is repeated in Services and Work anyway. */
    .mm-cluster p { display: none; }

    .mm-word { font-size: clamp(28px, 9vw, 46px); }

    .mm-preview { display: none; }
    .mm-zoom { display: none; }
    .mm-bar { justify-content: flex-start; }
}

/* --------------------------------------------------------------------------
   15. Hardware insert (dark)
   -------------------------------------------------------------------------- */

.insert { position: relative; }

.insert::before,
.insert::after {
    content: '';
    position: absolute;
    left: 0; right: 0;
    height: 1px;
    background: var(--clay);
    opacity: .5;
}
.insert::before { top: 0; }
.insert::after { bottom: 0; }

.caps {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 1px;
    background: var(--rule);
    border: 1px solid var(--rule);
    margin-top: clamp(34px, 4vw, 56px);
}

.cap {
    background: var(--paper);
    padding: clamp(22px, 2.6vw, 32px);
    transition: background-color .55s var(--ease);
}
.cap:hover { background: var(--surface); }

.cap-icon { color: var(--clay); margin-bottom: 20px; }
.cap-icon svg { width: 26px; height: 26px; }

.cap h3 {
    font-family: var(--font-display);
    font-size: 20px;
    font-weight: 500;
    letter-spacing: -.02em;
    line-height: 1.16;
    margin-bottom: 10px;
}

.cap p { font-size: 14px; line-height: 1.6; color: var(--ink-mute); }
.cap .meta { margin-top: 16px; font-size: 9.5px; }

.spotlight {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(30px, 4.4vw, 72px);
    align-items: center;
    margin-top: clamp(48px, 6vw, 88px);
}

.spotlight-plates {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(9px, 1.1vw, 14px);
}

/* --------------------------------------------------------------------------
   16. Process
   -------------------------------------------------------------------------- */

.steps {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0;
    margin-top: clamp(34px, 4vw, 58px);
    border-top: 1px solid var(--ink);
}

.step {
    padding: clamp(24px, 3vw, 40px) clamp(16px, 2vw, 30px) clamp(24px, 3vw, 36px) 0;
    position: relative;
    transition: background-color .55s var(--ease);
}

.step + .step { padding-left: clamp(18px, 2.2vw, 32px); border-left: 1px solid var(--rule); }

.step-num {
    font-family: var(--font-display);
    font-size: clamp(46px, 5.4vw, 78px);
    line-height: .9;
    letter-spacing: -.045em;
    color: var(--rule);
    transition: color .6s var(--ease);
    margin-bottom: 18px;
}

.step:hover .step-num { color: var(--clay); }

.step h3 {
    font-family: var(--font-display);
    font-size: clamp(19px, 1.9vw, 25px);
    font-weight: 500;
    letter-spacing: -.02em;
    margin-bottom: 10px;
}

.step p { font-size: 14.5px; line-height: 1.62; color: var(--ink-mute); }

/* --------------------------------------------------------------------------
   17. Technology
   -------------------------------------------------------------------------- */

.stacks {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 1px;
    background: var(--rule);
    border: 1px solid var(--rule);
    margin-top: clamp(34px, 4vw, 58px);
}

.stack { background: var(--paper); padding: clamp(18px, 2.2vw, 26px); }

.stack-label {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--clay);
    padding-bottom: 14px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--rule);
}

.stack-item {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 11px 0;
    border-bottom: 1px solid var(--rule-soft);
    transition: padding-left .5s var(--ease);
}

.stack-item:last-child { border-bottom: 0; }
.stack-item:hover { padding-left: 6px; }

.stack-item img {
    width: 19px; height: 19px;
    object-fit: contain;
    filter: grayscale(1) contrast(.85) opacity(.75);
    transition: filter .5s var(--ease);
    flex-shrink: 0;
}

.stack-item:hover img { filter: grayscale(0) contrast(1) opacity(1); }

.stack-item span {
    font-size: 13.5px;
    color: var(--ink-soft);
    transition: color .4s ease;
}
.stack-item:hover span { color: var(--ink); }

/* --------------------------------------------------------------------------
   18. Testimonials
   -------------------------------------------------------------------------- */

.quotes { margin-top: clamp(34px, 4vw, 58px); border-top: 1px solid var(--ink); }

.quote {
    display: grid;
    grid-template-columns: minmax(0, 268px) minmax(0, 1fr);
    gap: clamp(20px, 4vw, 68px);
    padding: clamp(30px, 3.6vw, 52px) 0;
    border-bottom: 1px solid var(--rule);
    align-items: start;
}

.quote-by { display: flex; align-items: center; gap: 14px; }

.quote-avatar {
    width: 46px; height: 46px;
    border: 1px solid var(--ink);
    display: grid;
    place-items: center;
    font-family: var(--font-mono);
    font-size: 12px;
    letter-spacing: .06em;
    flex-shrink: 0;
    transition: background-color .5s var(--ease), color .5s var(--ease);
}

.quote:hover .quote-avatar { background: var(--ink); color: var(--paper); }

.quote-by strong { display: block; font-size: 15px; font-weight: 600; }
.quote-by .meta { font-size: 10px; margin-top: 4px; letter-spacing: .07em; line-height: 1.55; }

.quote-stars { font-size: 11px; letter-spacing: .18em; color: var(--clay); margin-bottom: 16px; }

.quote p {
    font-family: var(--font-display);
    font-size: clamp(17px, 1.75vw, 23px);
    line-height: 1.44;
    letter-spacing: -.014em;
    color: var(--ink);
    text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   19. Insights
   -------------------------------------------------------------------------- */

.articles {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1px;
    background: var(--rule);
    border: 1px solid var(--rule);
    margin-top: clamp(34px, 4vw, 58px);
}

.article {
    background: var(--paper);
    padding: clamp(26px, 3.2vw, 44px);
    display: flex;
    flex-direction: column;
    gap: 14px;
    transition: background-color .55s var(--ease);
}

.article:hover { background: var(--surface); }

.article-meta { display: flex; align-items: center; gap: 10px; }

.article-tag {
    font-family: var(--font-mono);
    font-size: 9.5px;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: #FFF7F1;
    background: var(--ink);
    padding: 5px 9px;
}

.article h3 {
    font-family: var(--font-display);
    font-size: clamp(22px, 2.3vw, 31px);
    font-weight: 500;
    line-height: 1.12;
    letter-spacing: -.025em;
    text-wrap: balance;
}

.article p { color: var(--ink-soft); font-size: 15px; line-height: 1.62; }
.article .link { margin-top: auto; padding-top: 8px; align-self: flex-start; }

.center-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    justify-content: center;
    margin-top: clamp(30px, 3.4vw, 44px);
}

/* --------------------------------------------------------------------------
   20. Clay CTA band
   -------------------------------------------------------------------------- */

.band-clay .cta-inner {
    display: grid;
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    gap: clamp(28px, 4vw, 72px);
    align-items: end;
}

.band-clay .btn { border-color: var(--ink); color: var(--ink); }
.band-clay .btn::before { background: var(--ink); }
.band-clay .btn:hover { color: var(--paper); }
.band-clay .btn-solid { background: var(--ink); color: var(--paper); }
.band-clay .btn-solid::before { background: #FFF; }
.band-clay .btn-solid:hover { color: var(--paper); }

/* --------------------------------------------------------------------------
   21. Contact
   -------------------------------------------------------------------------- */

.contact-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    gap: clamp(34px, 4.6vw, 78px);
    margin-top: clamp(34px, 4vw, 58px);
    align-items: start;
}

.field { position: relative; margin-bottom: 26px; }

.field label {
    display: block;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--ink-mute);
    margin-bottom: 9px;
}

.field input,
.field select,
.field textarea {
    width: 100%;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--rule);
    border-radius: 0;
    padding: 11px 0;
    font-family: var(--font-body);
    font-size: 16px;
    color: var(--ink);
    transition: border-color .5s var(--ease);
    -webkit-appearance: none;
    appearance: none;
}

.field textarea { resize: vertical; min-height: 120px; line-height: 1.6; }

.field select {
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='7' viewBox='0 0 11 7'%3E%3Cpath d='M1 1l4.5 4.5L10 1' fill='none' stroke='%237C7266' stroke-width='1.2'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 2px center;
    padding-right: 24px;
}

.field input::placeholder,
.field textarea::placeholder { color: var(--ink-mute); opacity: .55; }

.field input:focus,
.field select:focus,
.field textarea:focus { outline: none; border-bottom-color: var(--clay); }

.field::after {
    content: '';
    position: absolute;
    left: 0; bottom: 0;
    height: 1px; width: 100%;
    background: var(--clay);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform .6s var(--ease);
    pointer-events: none;
}
.field:focus-within::after { transform: scaleX(1); }

.field-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(18px, 2.4vw, 34px);
}

.contact-card {
    background: var(--surface);
    border: 1px solid var(--rule);
    padding: clamp(26px, 3vw, 38px);
}

.contact-card h3 {
    font-family: var(--font-display);
    font-size: clamp(22px, 2.2vw, 29px);
    font-weight: 500;
    letter-spacing: -.024em;
    line-height: 1.1;
    margin-bottom: 14px;
}

.contact-card > p { color: var(--ink-soft); font-size: 15px; line-height: 1.62; }

.contact-line {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 0;
    border-bottom: 1px solid var(--rule);
    font-size: 14.5px;
}
.contact-line:first-of-type { margin-top: 22px; border-top: 1px solid var(--rule); }
.contact-line svg { width: 17px; height: 17px; color: var(--clay); flex-shrink: 0; }

.btn-whatsapp {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 11px;
    width: 100%;
    margin-top: 24px;
    padding: 16px 20px;
    background: var(--forest);
    color: #F1EBE1;
    border: 1px solid var(--forest);
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .17em;
    text-transform: uppercase;
    transition: background-color .5s var(--ease), color .5s var(--ease);
}
.btn-whatsapp svg { width: 17px; height: 17px; }
.btn-whatsapp:hover { background: transparent; color: var(--forest); }

.trust { margin-top: 24px; }

.trust-item {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 11px 0;
    font-size: 14px;
    color: var(--ink-soft);
}
.trust-item svg { width: 15px; height: 15px; color: var(--clay); flex-shrink: 0; }

/* Injected by tracking.js on successful submit */
.form-success, .form-success-b {
    text-align: center;
    padding: clamp(40px, 6vw, 76px) 20px;
    border: 1px solid var(--rule);
    background: var(--surface);
}
.form-success svg, .form-success-b svg { margin: 0 auto 22px; color: var(--clay); width: 46px; height: 46px; }
.form-success h3, .form-success-b h3 {
    font-family: var(--font-display);
    font-size: 30px;
    font-weight: 500;
    letter-spacing: -.025em;
    margin-bottom: 10px;
}
.form-success p, .form-success-b p { color: var(--ink-soft); max-width: 40ch; margin: 0 auto; }

/* --------------------------------------------------------------------------
   22. Footer
   -------------------------------------------------------------------------- */

.footer {
    background: var(--paper);
    border-top: 1px solid var(--ink);
    padding: clamp(48px, 6vw, 88px) 0 32px;
}

.footer-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr));
    gap: clamp(28px, 4vw, 64px);
}

.footer-brand p {
    margin-top: 20px;
    font-size: 14.5px;
    line-height: 1.65;
    color: var(--ink-mute);
    max-width: 40ch;
}

.footer-col h4 {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--clay);
    padding-bottom: 14px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--rule);
}

.footer-col a {
    display: block;
    padding: 9px 0;
    font-size: 14px;
    color: var(--ink-soft);
    transition: color .4s ease, padding-left .5s var(--ease);
}
.footer-col a:hover { color: var(--clay); padding-left: 6px; }

.footer-bottom {
    display: flex;
    flex-wrap: wrap;
    gap: 12px 26px;
    justify-content: space-between;
    align-items: center;
    margin-top: clamp(40px, 5vw, 68px);
    padding-top: 24px;
    border-top: 1px solid var(--rule);
}

/* --------------------------------------------------------------------------
   23. Lightbox
   -------------------------------------------------------------------------- */

.lightbox {
    position: fixed;
    inset: 0;
    z-index: 150;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 24px;
}

.lightbox.open { display: flex; }

.lightbox-veil {
    position: absolute;
    inset: 0;
    background: rgba(20, 17, 13, .93);
    opacity: 0;
    transition: opacity .5s ease;
}
.lightbox.open .lightbox-veil { opacity: 1; }

.lightbox-stage {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: clamp(12px, 3vw, 36px);
    opacity: 0;
    transform: translateY(16px);
    transition: opacity .55s var(--ease) .1s, transform .55s var(--ease) .1s;
}
.lightbox.open .lightbox-stage { opacity: 1; transform: none; }

.lightbox-figure { text-align: center; }

.lightbox-figure img {
    max-height: min(76vh, 760px);
    width: auto;
    border: 1px solid rgba(241, 235, 225, .18);
    background: #14110D;
}

.lightbox-cap {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: rgba(241, 235, 225, .62);
    margin-top: 16px;
}

.lightbox-btn {
    width: 46px; height: 46px;
    display: grid;
    place-items: center;
    background: transparent;
    border: 1px solid rgba(241, 235, 225, .28);
    color: #F1EBE1;
    cursor: pointer;
    flex-shrink: 0;
    transition: background-color .4s var(--ease), border-color .4s var(--ease);
}
.lightbox-btn:hover { background: var(--clay); border-color: var(--clay); }

.lightbox-close {
    position: absolute;
    top: 20px; right: 20px;
    z-index: 2;
}

/* --------------------------------------------------------------------------
   24. WhatsApp float
   -------------------------------------------------------------------------- */

.whatsapp-float {
    position: fixed;
    right: clamp(16px, 2.4vw, 30px);
    bottom: clamp(16px, 2.4vw, 30px);
    z-index: 90;
    width: 54px; height: 54px;
    display: grid;
    place-items: center;
    background: var(--forest);
    color: #F1EBE1;
    border: 1px solid var(--forest);
    transition: background-color .5s var(--ease), color .5s var(--ease), transform .5s var(--ease);
}
.whatsapp-float svg { width: 23px; height: 23px; fill: currentColor; }
.whatsapp-float:hover { background: var(--clay); border-color: var(--clay); transform: translateY(-3px); }

/* --------------------------------------------------------------------------
   25. Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 1080px) {
    .stacks { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .caps   { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .steps  { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .step:nth-child(3) { border-left: 0; }
    .step:nth-child(n+3) { border-top: 1px solid var(--rule); }
    .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
    .nav { display: none; }
    .nav-cta { display: none; }
    .menu-toggle { display: block; }

    .hero-deck   { grid-template-columns: 1fr; }
    .rotator-box { border-left: 0; border-top: 1px solid var(--rule); padding-left: 0; padding-top: 24px; }
    .about-grid  { grid-template-columns: 1fr; }
    .spread      { grid-template-columns: 1fr; }
    .spotlight   { grid-template-columns: 1fr; }
    .entries     { grid-template-columns: 1fr; }
    .sites       { grid-template-columns: 1fr; }
    .articles    { grid-template-columns: 1fr; }
    .contact-grid { grid-template-columns: 1fr; }
    .band-clay .cta-inner { grid-template-columns: 1fr; }
    .quote       { grid-template-columns: 1fr; gap: 20px; }
    .quote-by    { order: 2; }

    .head { grid-template-columns: 1fr; gap: 16px; }
    .head-folio { padding-top: 0; }

    .index-row { grid-template-columns: 40px minmax(0, 1fr); }
    .index-row .index-body { grid-column: 2; }

    .entries > .entry { padding-left: 0; padding-right: 0; }
}

@media (max-width: 640px) {
    body { font-size: 16px; }
    .colophon { grid-template-columns: 1fr; }
    .colophon-item + .colophon-item {
        padding-left: 0;
        border-left: 0;
        border-top: 1px solid var(--rule);
    }
    .colophon-label { max-width: none; }
    .stacks { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .caps   { grid-template-columns: 1fr; }
    .steps  { grid-template-columns: 1fr; }
    .step + .step { border-left: 0; border-top: 1px solid var(--rule); padding-left: 0; }
    .footer-grid { grid-template-columns: 1fr; }
    .entry-specs { grid-template-columns: 1fr; }
    .field-row { grid-template-columns: 1fr; gap: 0; }
    .lightbox-stage { gap: 8px; }
    .lightbox-btn { width: 38px; height: 38px; }
    .sub-head { align-items: flex-start; flex-direction: column; }
}

@media (max-width: 420px) {
    .stacks { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   26. Reduced motion
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }

    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }

    [data-reveal] { opacity: 1 !important; transform: none !important; clip-path: none !important; }
    [data-reveal="rule"] { transform: scaleX(1) !important; }
    [data-reveal="plate"] img { transform: none !important; }
    .mask-line > span { transform: none !important; }
    .cursor-dot, .cursor-ring { display: none; }
    .ticker-track { animation: none; }
}

/* --------------------------------------------------------------------------
   27. Focus visibility
   -------------------------------------------------------------------------- */

:focus-visible {
    outline: 2px solid var(--clay);
    outline-offset: 3px;
}

/* ==========================================================================
   28. Interior pages — blog, case studies, websites
   ==========================================================================
   These pages keep their original markup untouched (every heading, link and
   paragraph stays exactly where it was, so nothing shifts for search), and
   the legacy class names are simply re-dressed in the editorial language.
   ========================================================================== */

.container {
    width: 100%;
    max-width: var(--max);
    margin: 0 auto;
    padding: 0 var(--gutter);
}

/* Legacy cursor layer — the editorial one replaces it. */
.cursor-glow { display: none; }

/* Flat paper instead of glass. */
.glass-card,
.glass-cta {
    background: var(--surface);
    border: 1px solid var(--rule);
    backdrop-filter: none;
}

.gradient-text {
    color: var(--clay);
    font-style: italic;
    background: none;
    -webkit-text-fill-color: currentColor;
}

/* --- Section headings ---------------------------------------------------- */

.section-label {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .22em;
    text-transform: uppercase;
    color: var(--clay);
    margin-bottom: 18px;
}

.section-title {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(34px, 5.2vw, 68px);
    line-height: 1.02;
    letter-spacing: -.028em;
    font-variation-settings: "opsz" 42;
    text-wrap: balance;
}

.section-subtitle {
    font-size: clamp(17px, 1.35vw, 20px);
    line-height: 1.62;
    color: var(--ink-soft);
    max-width: 58ch;
    margin-top: 20px;
}

.centered { text-align: center; }
.centered.section-subtitle { margin-left: auto; margin-right: auto; }

/* --- Index heroes -------------------------------------------------------- */

.blog-hero,
.websites-hero {
    padding-top: calc(var(--nav-h) + clamp(48px, 7vw, 104px));
    padding-bottom: clamp(28px, 4vw, 56px);
    border-bottom: 1px solid var(--rule);
}

/* --- Card grids ---------------------------------------------------------- */

.blog-grid,
.websites-grid,
.websites-grid-full {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 1px;
    background: var(--rule);
    border: 1px solid var(--rule);
    margin-top: clamp(30px, 4vw, 52px);
}

.blog-card {
    background: var(--paper);
    border: 0;
    padding: clamp(26px, 3.2vw, 44px);
    display: flex;
    flex-direction: column;
    gap: 14px;
    transition: background-color .55s var(--ease);
}
.blog-card:hover { background: var(--surface); }

.blog-card-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--ink-mute);
}

.blog-card-tag {
    font-family: var(--font-mono);
    font-size: 9.5px;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: #FFF7F1;
    background: var(--ink);
    padding: 5px 9px;
}

.blog-card h3 {
    font-family: var(--font-display);
    font-size: clamp(21px, 2.2vw, 30px);
    font-weight: 500;
    line-height: 1.12;
    letter-spacing: -.025em;
    font-variation-settings: "opsz" 42;
    text-wrap: balance;
}

.blog-card p { color: var(--ink-soft); font-size: 15px; line-height: 1.62; }

.blog-card-link,
.article-back,
.back-link {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .15em;
    text-transform: uppercase;
    color: var(--clay);
    padding-bottom: 3px;
    position: relative;
    align-self: flex-start;
}
.blog-card-link { margin-top: auto; }

.blog-card-link::after,
.article-back::after,
.back-link::after {
    content: '';
    position: absolute;
    left: 0; bottom: 0;
    width: 100%; height: 1px;
    background: currentColor;
    transform-origin: right center;
    transition: transform .55s var(--ease);
}
.blog-card-link:hover::after,
.article-back:hover::after,
.back-link:hover::after { transform: scaleX(0); }

.blog-card-link svg,
.article-back svg { transition: transform .55s var(--ease); }
.blog-card-link:hover svg { transform: translateX(5px); }
.article-back:hover svg { transform: translateX(-5px); }

/* --- Long-form article --------------------------------------------------- */

.article-hero {
    padding-top: calc(var(--nav-h) + clamp(40px, 6vw, 86px));
    padding-bottom: clamp(26px, 3.4vw, 46px);
    border-bottom: 1px solid var(--rule);
}

.article-hero h1 {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(34px, 5vw, 66px);
    line-height: 1.04;
    letter-spacing: -.028em;
    font-variation-settings: "opsz" 60;
    max-width: 100%;
    text-wrap: balance;
    margin-top: 18px;
}

.article-subtitle {
    font-size: clamp(17px, 1.4vw, 21px);
    line-height: 1.6;
    color: var(--ink-soft);
    max-width: 56ch;
    margin-top: 22px;
}

.article-body {
    padding-top: clamp(40px, 5vw, 76px);
    padding-bottom: clamp(40px, 5vw, 76px);
    font-size: 17.5px;
    line-height: 1.72;
    color: var(--ink-soft);
}

/* An article reads as one centred column. The words inside stay left-aligned
   (ragged right); it is the column that is centred on the page, so the hero
   and the body share the same measure and the same optical centre.

   The measure is in rem, not ch: `ch` resolves against each element's own
   font-size, and the body runs at 17.5px against the hero's 17px, which left
   the two columns 23px apart and their left edges visibly misaligned. */
.article-hero > .container,
.article-body.container {
    max-width: calc(var(--measure) + var(--gutter) * 2);
}

/* Everything sits inside the measure — figures included. Letting images
   break out wider than the text reads as an accident rather than a choice:
   the eye has no column edge to hold on to, and at the top of a scroll the
   picture looks like it has escaped the article. One edge, all the way down. */
.article-body > .article-figure,
.article-body > .article-figure-grid,
.article-body > .article-table {
    width: 100%;
    margin-left: 0;
    translate: none;
}

/* A table is sized by its content, so a narrow screen cannot simply squeeze
   it — left alone it widens the whole document and the page scrolls
   sideways. Give it its own scroll container so the overflow stays inside
   the table instead of escaping to the body. */
.article-table-scroll,
.article-body > .article-table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.article-body > h2 {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(26px, 3vw, 38px);
    line-height: 1.14;
    letter-spacing: -.024em;
    font-variation-settings: "opsz" 42;
    color: var(--ink);
    margin: clamp(40px, 4.6vw, 64px) 0 18px;
}

.article-body > h3 {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(20px, 2.1vw, 26px);
    line-height: 1.2;
    letter-spacing: -.018em;
    color: var(--ink);
    margin: clamp(28px, 3vw, 40px) 0 12px;
}

.article-body p { margin-bottom: 1.15em; }
.article-body strong { color: var(--ink); font-weight: 600; }

.article-body ul,
.article-body ol { margin: 0 0 1.3em 1.1em; }
.article-body li { margin-bottom: .55em; padding-left: .3em; }
.article-body li::marker { color: var(--clay); }

/* Prose links only. Without the :not(), this beats .btn-primary on
   specificity (0,1,1 against 0,1,0) and repaints every button inside an
   article in clay-on-ink — unreadable — with the underline gradient
   showing as a stray rule beneath it. */
.article-body a:not(.btn):not(.back-link):not(.article-back) {
    color: var(--clay);
    background-image: linear-gradient(var(--clay), var(--clay));
    background-size: 100% 1px;
    background-position: 0 100%;
    background-repeat: no-repeat;
    transition: background-size .5s var(--ease);
}
.article-body a:not(.btn):not(.back-link):not(.article-back):hover { background-size: 0 1px; }

.article-table {
    width: 100%;
    border-collapse: collapse;
    margin: clamp(24px, 3vw, 38px) 0;
    font-size: 15px;
}
.article-table th,
.article-table td { padding: 14px 16px; border-bottom: 1px solid var(--rule); text-align: left; }
.article-table thead th {
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--ink-mute);
    border-bottom-color: var(--ink);
}
.article-table tbody tr:hover { background: var(--surface); }

.article-callout {
    border-left: 2px solid var(--clay);
    background: var(--surface);
    padding: clamp(20px, 2.4vw, 30px);
    margin: clamp(28px, 3.4vw, 44px) 0;
}
.article-callout p:last-child { margin-bottom: 0; }

.article-figure { margin: clamp(28px, 3.4vw, 44px) 0; }

/* A photo must not outgrow the screen. Filling the measure sounds right
   until the source is portrait: a 1242x2688 phone screenshot at a 792px
   column is 1738px tall — nearly two viewports — so you scroll a whole
   screen and still cannot see one picture. Cap the height and let the width
   fall back, which shrinks tall images and leaves landscape ones alone. */
.article-figure img,
.article-figure-grid img {
    display: block;
    width: auto;
    max-width: 100%;
    max-height: 76vh;
    margin-inline: auto;
    border: 1px solid var(--rule);
}
.article-figure figcaption {
    font-family: var(--font-mono);
    font-size: 9.5px;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--ink-mute);
    margin-top: 10px;
}

.article-figure-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: clamp(10px, 1.4vw, 18px);
}

/* --- Tail-end blocks ----------------------------------------------------- */

.article-cta {
    padding: clamp(28px, 3.4vw, 46px);
    margin-top: clamp(34px, 4vw, 56px);
}
.article-cta h3 {
    font-family: var(--font-display);
    font-size: clamp(22px, 2.4vw, 31px);
    font-weight: 500;
    letter-spacing: -.024em;
    line-height: 1.1;
    margin-bottom: 12px;
}

/* This block sits outside .container, so it needs its own measure — without
   one it ran the full 1440px while the article above it sat in a centred
   792px column. */
.related-posts {
    max-width: calc(var(--measure) + var(--gutter) * 2);
    margin: clamp(40px, 5vw, 72px) auto clamp(56px, 6vw, 88px);
    padding: clamp(28px, 3.4vw, 44px) var(--gutter) 0;
    border-top: 1px solid var(--ink);
}

/* h4 as well as h3: the pages use <h4> here, so targeting h3 alone left the
   heading rendering as plain bold body text. */
.related-posts h3,
.related-posts h4 {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .22em;
    text-transform: uppercase;
    color: var(--clay);
    margin-bottom: 6px;
}

/* Anchors are inline by default, so all three titles ran together as one
   paragraph. They are a list of destinations — one per row. */
.related-posts a {
    display: block;
    padding: 15px 0;
    border-bottom: 1px solid var(--rule);
    font-family: var(--font-display);
    font-size: clamp(17px, 1.5vw, 21px);
    font-weight: 500;
    line-height: 1.25;
    letter-spacing: -.014em;
    color: var(--ink);
    position: relative;
    transition: color .4s var(--ease), padding-left .4s var(--ease);
}
.related-posts a::after {
    content: '\2192';
    position: absolute;
    right: 0;
    opacity: 0;
    transform: translateX(-6px);
    transition: opacity .4s var(--ease), transform .4s var(--ease);
}
.related-posts a:hover {
    color: var(--clay);
    padding-left: 10px;
}
.related-posts a:hover::after { opacity: 1; transform: translateX(0); }

.blog-hero + .section,
.websites-hero + .section { padding-top: clamp(40px, 5vw, 72px); }

.cta-section {
    border-top: 1px solid var(--rule);
    padding-top: clamp(52px, 6vw, 92px);
    padding-bottom: clamp(52px, 6vw, 92px);
}
.cta-box {
    text-align: center;
    padding: clamp(40px, 5vw, 76px) clamp(24px, 4vw, 56px);
}
.cta-box h2 {
    font-family: var(--font-display);
    font-size: clamp(28px, 4vw, 52px);
    font-weight: 500;
    line-height: 1.06;
    letter-spacing: -.028em;
    font-variation-settings: "opsz" 42;
    margin-bottom: 16px;
    text-wrap: balance;
}
.cta-box p { color: var(--ink-soft); max-width: 52ch; margin: 0 auto 28px; }

/* --- websites.html ------------------------------------------------------- */

.website-card { background: var(--paper); padding: clamp(22px, 2.6vw, 34px); }

.browser-mockup { border: 1px solid var(--rule); background: var(--surface); overflow: hidden; }
.browser-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 12px;
    border-bottom: 1px solid var(--rule);
    background: var(--paper-deep);
}
.browser-dots { display: flex; gap: 5px; }
.browser-dots span { width: 7px; height: 7px; border-radius: 50%; background: var(--rule); }
.browser-url {
    font-family: var(--font-mono);
    font-size: 9.5px;
    letter-spacing: .06em;
    color: var(--ink-mute);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.browser-content { position: relative; aspect-ratio: 16 / 10; }
.browser-content img { width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.browser-placeholder {
    position: absolute; inset: 0;
    display: grid; place-items: center; gap: 8px;
    color: var(--ink-mute);
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .16em;
    text-transform: uppercase;
}
.browser-content img + .browser-placeholder { display: none; }

.website-card-info { margin-top: 20px; }
.website-card-info h4 {
    font-family: var(--font-display);
    font-size: clamp(20px, 2.1vw, 26px);
    font-weight: 500;
    letter-spacing: -.02em;
    line-height: 1.1;
    margin-bottom: 6px;
}

.work-category {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--ink-mute);
}
.work-description { font-size: 15px; color: var(--ink-soft); line-height: 1.6; margin-top: 10px; max-width: 46ch; }

.work-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 20px; }
.work-tags span,
.store-tag {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: .15em;
    text-transform: uppercase;
    padding: 7px 12px;
    border: 1px solid var(--rule);
    color: var(--ink-mute);
}
a.store-tag {
    border-color: var(--ink);
    color: var(--ink);
    transition: background-color .45s var(--ease), color .45s var(--ease);
}
a.store-tag:hover { background: var(--ink); color: var(--paper); }

/* --- Button alias -------------------------------------------------------- */

.btn-primary {
    background: var(--ink);
    color: var(--paper);
    border-color: var(--ink);
}
.btn-primary::before { background: var(--clay); }
.btn-primary:hover { color: #FFF7F1; border-color: var(--clay); }

@media (max-width: 640px) {
    .blog-grid, .websites-grid, .websites-grid-full { grid-template-columns: 1fr; }
    .article-body { font-size: 16.5px; }
}

/* ==========================================================================
   29. TRIAL — Anthropic type, site-wide
   ==========================================================================
   TEMPORARY. Revert the commit that added this to remove it cleanly.

   These typefaces are Anthropic's proprietary corporate faces, renamed on
   disk only — the internal name table still reads 'Anthropic Sans Web' and
   the vendor is BSPK LLC. They are here to preview a look, not to ship.
   Do not merge this to main or leave it on a public URL.

   Every "opsz" value pinned above is calibrated to Fraunces' 9..144 axis and
   is meaningless on Anthropic Serif's 16..48 axis, where 66 simply clamps to
   48 and 42 lands nowhere near the intended weight. Release them all so the
   trial face uses its own automatic optical sizing.

   This block sits last on purpose: the pins in section 28 match it for
   specificity, so only source order decides, and it has to come after them.
   ========================================================================== */

html[data-fonts="anthropic"] * { font-variation-settings: normal; }
