/* ===========================================================================
   THEME — "CONSOLE"  (direction B, approved by Zach)

   Dark, near-monochrome, laid out with the precision of a specification sheet.
   Ordinary horizontal navigation; the character is in the type.

     · extreme scale contrast — 10px mono metadata against 120px display type
     · hairline rules and three greys, no chromatic accent at all, so the
       photographs are the only colour on the page
     · photographs as a contact sheet: tight gutters, varying spans
     · numbers and metadata always in mono, prose always in Archivo

   HOW THIS FILE WORKS
   This replaces base.css wholesale — see theme_stylesheet() in public/index.php,
   driven by the 'theme' key in app/config.php. It styles the same class names
   the templates already emit, so switching themes never touches the markup.
   Read it top to bottom: tokens, primitives, shell, then one block per page.

   Section order mirrors base.css so the two can be compared side by side.
   =========================================================================== */

/* --- Typefaces -------------------------------------------------------------
   Self-hosted so the site owes nothing to Google, works behind the preview
   password, and renders the same offline. Latin subset only; swap keeps text
   visible while the files load. */

@font-face {
    font-family: 'Archivo';
    src: url('/assets/fonts/archivo-400.woff2') format('woff2');
    font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
    font-family: 'Archivo';
    src: url('/assets/fonts/archivo-500.woff2') format('woff2');
    font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
    font-family: 'Archivo';
    src: url('/assets/fonts/archivo-600.woff2') format('woff2');
    font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
    font-family: 'JetBrains Mono';
    src: url('/assets/fonts/jetbrains-mono-400.woff2') format('woff2');
    font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
    font-family: 'JetBrains Mono';
    src: url('/assets/fonts/jetbrains-mono-500.woff2') format('woff2');
    font-weight: 500; font-style: normal; font-display: swap;
}

/* --- Tokens ----------------------------------------------------------------
   Same names as base.css, so anything written against the scaffold keeps
   working. The ground is deliberately not pure black: black flattens
   photographs and makes the hairlines look like cracks. */

:root {
    --ground:     #0e0f11;   /* page */
    --ground-2:   #16181c;   /* raised rows, inputs, hovers */
    --ground-3:   #1c1f24;   /* rarely: a panel on a raised row */
    --ink:        #f1f2f4;   /* body text and headings */
    --ink-2:      #8a9099;   /* secondary text */
    --ink-3:      #5b616a;   /* metadata, labels, captions */
    --rule:       #23262b;   /* hairline */
    --rule-2:     #33373e;   /* the heavier rule that opens a table */
    --accent:     #e8eaed;   /* achromatic on purpose: the accent is light itself */
    --accent-ink: #0e0f11;   /* text on the accent */

    --display: 'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --ui:      'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --mono:    'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

    /* Page gutter grows with the viewport; --wrap keeps base.css's contract. */
    --edge: clamp(20px, 3.4vw, 52px);
    --wrap: 1320px;

    /* The two knobs the client can move in Appearance. Defaults are the design
       as approved; appearance.css overrides them when they change something. */
    --text-base: 16px;
    --space-scale: 1;
}

/* --- Primitives ----------------------------------------------------------- */

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

body {
    margin: 0;
    /* Nothing should ever scroll sideways on a phone. */
    overflow-x: hidden;
    background: var(--ground);
    color: var(--ink);
    font: 400 var(--text-base)/1.62 var(--ui);
    -webkit-font-smoothing: antialiased;
    -webkit-text-size-adjust: 100%;
}

img { display: block; max-width: 100%; height: auto; }
a   { color: inherit; text-underline-offset: 3px; }

h1, h2, h3 { font-weight: 600; letter-spacing: -.025em; line-height: 1.15; text-wrap: balance; }

/* The two utility voices used throughout: mono for anything machine-ish
   (counts, years, timestamps) and a wide-tracked label for section eyebrows. */
.count,
.credit__year,
.breadcrumb,
.photo__caption,
.site-header__where { font: 400 10.5px/1.5 var(--mono); letter-spacing: .06em; color: var(--ink-3); }

.wrap   { max-width: var(--wrap); margin: 0 auto; padding-inline: var(--edge); }
.narrow { max-width: 720px; }
.muted  { color: var(--ink-3); }
.hidden { display: none; }

.skip {
    position: absolute; left: -9999px;
    padding: 10px 16px; background: var(--ink); color: var(--ground);
}
.skip:focus { left: 8px; top: 8px; z-index: 60; }

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

::selection { background: var(--ink); color: var(--ground); }

/* --- Header ----------------------------------------------------------------
   Wordmark left, navigation right, sticky so the credit index keeps its
   bearings while scrolling a long list. */

.site-header {
    position: sticky; top: 0; z-index: 40;
    background: var(--ground);
    border-bottom: 1px solid var(--rule);
}
.site-header__inner { display: flex; align-items: center; gap: clamp(16px, 3vw, 40px); padding-block: 14px; }
.site-header__mark  { font-size: 14px; font-weight: 600; letter-spacing: -.015em; text-decoration: none; white-space: nowrap; }
.site-header__where { margin-left: auto; }

/* The hamburger and the panel it opens exist only on narrow screens; the
   media query near the end of this file turns them on. */
.nav-toggle,
.mobile-nav { display: none; }

.site-nav { display: flex; gap: clamp(12px, 2vw, 26px); margin-left: auto; }
/* When the location is shown it takes the auto margin, so the nav must not. */
.site-header__where ~ .site-nav { margin-left: 0; }
.site-nav a {
    font-size: 13.5px; color: var(--ink-2); text-decoration: none;
    padding-bottom: 3px; border-bottom: 1px solid transparent;
    transition: color .15s, border-color .15s;
}
.site-nav a:hover              { color: var(--ink); }
.site-nav a[aria-current]      { color: var(--ink); border-bottom-color: var(--ink); }

/* --- Footer --------------------------------------------------------------- */

.site-footer { margin-top: clamp(48px, 7vw, 96px); border-top: 1px solid var(--rule); }
.site-footer__inner {
    display: flex; justify-content: space-between; flex-wrap: wrap; gap: 16px;
    padding-block: 26px 52px;
    font-size: 13px; color: var(--ink-3);
}
.site-footer__links { display: flex; flex-wrap: wrap; gap: 18px; }
.site-footer a { color: var(--ink-2); text-decoration: none; transition: color .15s; }
.site-footer a:hover { color: var(--ink); }

/* --- Sections --------------------------------------------------------------
   Hairline between sections; the head is a baseline-aligned pair of a heading
   and its count or "all work" link. */

.section { padding-block: calc(clamp(44px, 6vw, 86px) * var(--space-scale)); }
.section + .section,
.case .section { border-top: 1px solid var(--rule); }
.section__head {
    display: flex; align-items: baseline; justify-content: space-between; gap: 20px;
    margin-bottom: clamp(20px, 2.6vw, 32px);
}
.section__head h1,
.section__head h2 { margin: 0; font-size: clamp(17px, 1.9vw, 22px); }
.section__head a  { font-size: 12.5px; color: var(--ink-2); text-decoration: none; }
.section__head a:hover { color: var(--ink); }

/* --- Opening block (home) --------------------------------------------------
   The whole direction in one gesture: 10px of mono metadata sitting directly
   under 120px of display type, with nothing in between to soften the jump. */

.hero { padding-block: calc(clamp(48px, 8vw, 104px) * var(--space-scale)) calc(clamp(30px, 4vw, 54px) * var(--space-scale)); }
.hero__claim {
    margin: 0;
    max-width: 16ch;
    font-size: clamp(44px, 9vw, 122px);
    line-height: .88;
    letter-spacing: -.048em;
}
.hero__lede {
    margin: clamp(26px, 3.4vw, 44px) 0 0;
    max-width: 44ch;
    font-size: clamp(17px, 2.2vw, 26px);
    font-weight: 500;
    line-height: 1.3;
    letter-spacing: -.02em;
    color: var(--ink-2);
}

/* --- Specification strip (the .facts definition list) ----------------------
   Key/value pairs divided by hairlines. The 1px gap over a rule-coloured
   background is what draws the dividers, so no borders are needed per cell. */

.facts {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(min(170px, 100%), 1fr));
    gap: 1px; margin: clamp(30px, 4vw, 52px) 0 0; padding: 0;
    background: var(--rule);
    border-block: 1px solid var(--rule);
}
.fact { display: grid; gap: 6px; padding: 16px 18px 16px 0; background: var(--ground); }
.fact dt { font: 500 9.5px/1.4 var(--ui); letter-spacing: .2em; text-transform: uppercase; color: var(--ink-3); }
.fact dd { margin: 0; font-size: 15px; }
.fact dd a { color: var(--ink); }

/* --- Credits ---------------------------------------------------------------
   A table without table markup: five aligned columns, hairline per row, and a
   hover that nudges the row right so the eye tracks it across the page. */

.credit-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule-2); }
.credit { border-bottom: 1px solid var(--rule); }
.credit__inner {
    display: grid;
    grid-template-columns: minmax(0, 2.2fr) minmax(0, 2fr) minmax(0, 1.4fr) 64px;
    gap: 4px 18px;
    align-items: baseline;
    padding: 15px 0;
    text-decoration: none; color: inherit;
    transition: background .14s, padding-left .14s;
}
a.credit__inner:hover { background: var(--ground-2); padding-left: 10px; }
.credit__artist  { font-size: 17px; font-weight: 500; letter-spacing: -.015em; }
.credit__release { font-size: 15px; color: var(--ink-2); }
.credit__role    { font: 500 9.5px/1.6 var(--ui); letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3); }
.credit__sep     { opacity: .5; }
.credit__year    { font: 400 13px/1.5 var(--mono); color: var(--ink-3); text-align: right; font-variant-numeric: tabular-nums; }

/* Role filter: quiet outlines until pressed, then the light "accent". */
.filters { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 22px; }
.filters button {
    padding: 6px 13px; border: 1px solid var(--rule-2); border-radius: 2px;
    background: transparent; color: var(--ink-2);
    font: 400 12px/1.4 var(--ui); cursor: pointer;
    transition: color .15s, border-color .15s, background .15s;
}
.filters button:hover { color: var(--ink); border-color: var(--ink-3); }
.filters button[aria-pressed="true"] {
    background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 500;
}

/* --- Case studies (cards) -------------------------------------------------- */

.project-list {
    list-style: none; margin: 0; padding: 0;
    display: grid; gap: clamp(20px, 2.4vw, 34px);
    grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 1fr));
}
.project-card a { display: grid; gap: 7px; text-decoration: none; color: inherit; }
.project-card img {
    margin-bottom: 10px; width: 100%; aspect-ratio: 3 / 2; object-fit: cover;
    background: var(--ground-2); transition: opacity .18s;
}
.project-card a:hover img      { opacity: .82; }
.project-card__meta            { font: 400 10.5px/1.5 var(--mono); letter-spacing: .06em; color: var(--ink-3); }
.project-card__title           { font-size: 19px; font-weight: 600; letter-spacing: -.02em; }
.project-card a:hover .project-card__title { text-decoration: underline; }
.project-card__summary         { font-size: 14.5px; line-height: 1.6; color: var(--ink-2); }

/* --- One case study --------------------------------------------------------- */

.breadcrumb { padding-block: 16px; }
.breadcrumb a { color: var(--ink-2); text-decoration: none; }
.breadcrumb a:hover { color: var(--ink); }

.case__head { padding-block: calc(clamp(40px, 6vw, 76px) * var(--space-scale)) calc(clamp(22px, 3vw, 34px) * var(--space-scale)); }
.case__meta {
    margin: 0 0 16px;
    font: 400 10.5px/1.5 var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3);
}
.case__head h1 { margin: 0; font-size: clamp(32px, 6vw, 68px); line-height: .95; letter-spacing: -.04em; }
.case__subtitle { margin: 16px 0 0; font-size: clamp(16px, 2vw, 21px); font-weight: 500; color: var(--ink-2); }
.case__summary  { margin: 12px 0 0; max-width: 52ch; font-size: 16.5px; line-height: 1.7; color: var(--ink-2); }

/* Prose: the first paragraph is the lede, set larger and brighter. */
.prose { max-width: 64ch; }
.prose p { margin: 0 0 1.2em; font-size: 16.5px; line-height: 1.78; color: #dcdee2; }
.prose p:first-of-type { font-size: 19px; line-height: 1.6; color: var(--ink); }
.prose a { color: var(--ink); }
.lede { font-size: 18px; line-height: 1.6; color: var(--ink-2); }

/* --- Full-bleed plate (home lead photograph, case study hero) ---------------- */

.plate { margin: 0; background: var(--ground-2); }
.plate img { width: 100%; max-height: 74vh; object-fit: cover; }
.plate figcaption { padding-block: 10px; font: 400 10.5px/1.5 var(--mono); letter-spacing: .06em; color: var(--ink-3); }

/* --- Contact sheet (photography) --------------------------------------------
   Six columns with 4px gutters. Spans repeat in a 6-frame cycle so a gallery
   of any length keeps the rhythm of a working contact sheet rather than a
   tidy grid. Captions sit over the frame and appear on hover or focus. */

.gallery { display: grid; grid-template-columns: repeat(6, 1fr); gap: 4px; }

.photo { position: relative; margin: 0; overflow: hidden; background: var(--ground-2); }
.photo__btn { display: block; width: 100%; height: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; }
.photo img  { width: 100%; height: 100%; object-fit: cover; transition: opacity .18s; }
.photo:hover img { opacity: .82; }

.photo:nth-child(6n + 1) { grid-column: span 4; aspect-ratio: 2 / 1; }
.photo:nth-child(6n + 2) { grid-column: span 2; aspect-ratio: 1 / 1; }
.photo:nth-child(6n + 3) { grid-column: span 2; aspect-ratio: 1 / 1; }
.photo:nth-child(6n + 4) { grid-column: span 4; aspect-ratio: 2 / 1; }
.photo:nth-child(6n + 5) { grid-column: span 3; aspect-ratio: 3 / 2; }
.photo:nth-child(6n)     { grid-column: span 3; aspect-ratio: 3 / 2; }

.photo__caption {
    position: absolute; inset: auto 0 0 0;
    padding: 26px 11px 9px;
    background: linear-gradient(to top, rgba(14, 15, 17, .9), rgba(14, 15, 17, 0));
    color: var(--ink);
    opacity: 0; transition: opacity .18s;
}
.photo:hover .photo__caption,
.photo:focus-within .photo__caption { opacity: 1; }

/* A case study's gallery is a quieter three-up: it supports the write-up
   rather than competing with it. */
.case .gallery { grid-template-columns: repeat(3, 1fr); gap: 6px; }
.case .photo[class] { grid-column: span 1; aspect-ratio: 3 / 2; }

/* --- Services as a spec list -------------------------------------------------
   Hairline-divided rows on a rule-coloured background, same trick as .facts. */

.service-list {
    display: grid; gap: 1px;
    grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
    background: var(--rule); border: 1px solid var(--rule);
}
.service-list--detail { grid-template-columns: 1fr; }
.service { padding: 22px clamp(18px, 2vw, 28px); background: var(--ground); }
.service h2, .service h3 { margin: 0 0 7px; font-size: 16px; }
.service p { margin: 0; font-size: 14.5px; line-height: 1.65; color: var(--ink-2); }
.service__summary { font-size: 15px; }

/* --- Gear -------------------------------------------------------------------- */

.gear { display: grid; gap: clamp(24px, 3vw, 40px); grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); }
.gear__group h3 {
    margin: 0 0 12px; padding-bottom: 9px; border-bottom: 1px solid var(--rule-2);
    font: 500 9.5px/1.4 var(--ui); letter-spacing: .2em; text-transform: uppercase; color: var(--ink-3);
}
.gear__group ul { margin: 0; padding: 0; list-style: none; }
.gear__group li { padding: 7px 0; border-bottom: 1px solid var(--rule); }
.gear__name   { display: block; font-size: 14.5px; }
.gear__detail { display: block; font: 400 10.5px/1.6 var(--mono); letter-spacing: .04em; color: var(--ink-3); }

/* --- Embeds ------------------------------------------------------------------- */

.embed { margin-block: clamp(24px, 3vw, 40px); }
.embed iframe { width: 100%; border: 0; }
.embed--youtube iframe  { aspect-ratio: 16 / 9; }
.embed--bandcamp iframe { height: 340px; }

/* --- Contact and forms --------------------------------------------------------- */

.contact { display: grid; gap: clamp(28px, 4vw, 56px); align-items: start; }
@media (min-width: 860px) { .contact { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.contact__intro,
.contact-intro { font-size: 16.5px; line-height: 1.7; color: var(--ink-2); }

.contact-form { max-width: 480px; }
.field { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
.field label { font: 500 9.5px/1.4 var(--ui); letter-spacing: .2em; text-transform: uppercase; color: var(--ink-3); }
.field input,
.field textarea {
    padding: 12px 14px; border: 1px solid var(--rule-2); border-radius: 2px;
    background: var(--ground-2); color: var(--ink);
    font: 400 15px/1.5 var(--ui);
    transition: border-color .15s;
}
.field input:focus,
.field textarea:focus { outline: none; border-color: var(--ink-2); }
.field input::placeholder,
.field textarea::placeholder { color: var(--ink-3); }

.honeypot, .hp { position: absolute; left: -9999px; }

.button {
    margin-top: 6px; padding: 14px 28px; border: 0; border-radius: 2px;
    background: var(--accent); color: var(--accent-ink);
    font: 600 13px/1 var(--ui); cursor: pointer;
    transition: opacity .15s;
}
.button:hover { opacity: .88; }

.form-status { margin: 12px 0 0; font-size: 14px; color: var(--ink-2); }
.form-status.err { color: #f0a8a8; }
.form-status.ok  { color: #a9dcc0; }
.hint { font-size: 12.5px; color: var(--ink-3); }

/* --- Lightbox -------------------------------------------------------------------
   Near-opaque so a photograph is the only thing in the room. */

.lightbox {
    position: fixed; inset: 0; z-index: 150;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
    padding: clamp(20px, 4vw, 44px);
    background: rgba(8, 9, 10, .97);
}
/* A class selector outranks the browser's built-in [hidden] rule, so the
   hidden state has to be restated or the overlay is always open. */
.lightbox[hidden] { display: none; }
.lightbox__figure  { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 14px; max-width: 100%; }
.lightbox__img     { max-width: 100%; max-height: 78vh; object-fit: contain; }
.lightbox__caption { font: 400 12px/1.5 var(--mono); letter-spacing: .04em; color: var(--ink-2); text-align: center; }
.lightbox button {
    position: absolute; padding: 12px 18px; border: 0; background: none;
    color: var(--ink); font-size: 26px; line-height: 1; cursor: pointer;
}
.lightbox__close { top: 14px; right: 18px; }
.lightbox__prev  { left: 10px;  top: 50%; transform: translateY(-50%); }
.lightbox__next  { right: 10px; top: 50%; transform: translateY(-50%); }

/* --- Empty states and small print --------------------------------------------- */

.empty { padding: 40px 0; color: var(--ink-3); }
.count { font-variant-numeric: tabular-nums; }

/* --- Narrow screens -------------------------------------------------------------
   The header collapses to a toggle, the credit table folds to two columns, and
   the contact sheet drops to two up. Everything else already reflows. */

@media (max-width: 860px) {
    .site-header__inner { flex-wrap: wrap; gap: 10px 18px; }
    .site-header__where { order: 3; margin-left: 0; width: 100%; }

    .gallery { grid-template-columns: repeat(2, 1fr); }
    .photo[class] { grid-column: span 1; aspect-ratio: 3 / 2; }
    .photo:nth-child(6n + 1)[class] { grid-column: span 2; aspect-ratio: 2 / 1; }
    .case .gallery { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 760px) {
    .site-nav { display: none; }
    .nav-toggle {
        display: flex; flex-direction: column; gap: 4px; margin-left: auto;
        padding: 10px; border: 0; background: none; cursor: pointer;
    }
    .nav-toggle span { display: block; width: 20px; height: 2px; background: var(--ink); }

    .mobile-nav { display: flex; flex-direction: column; padding: 4px var(--edge) 16px; }
    .mobile-nav[hidden] { display: none; }
    .mobile-nav a {
        padding: 12px 0; border-top: 1px solid var(--rule);
        text-decoration: none; color: var(--ink); font-size: 15px;
    }

    /* One fact per row: two columns leave an empty cell whenever the count
       is odd, which reads as a mistake. */
    .facts { grid-template-columns: 1fr; }

    /* Credits fold to artist + year, with release and role stacked beneath. */
    .credit__inner { grid-template-columns: minmax(0, 1fr) 56px; gap: 3px 12px; }
    .credit__release,
    .credit__role  { grid-column: 1; }
    .credit__year  { grid-column: 2; grid-row: 1; }

    .hero__claim { max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation: none !important; transition: none !important; }
}
