/* Self-hosted. See build/fonts and the note in build/fonts.py.
   Archivo is variable, so one file serves 400 through 900. */
@font-face{font-family:"Archivo";font-style:normal;font-weight:100 900;
  font-display:swap;src:url(/assets/fonts/archivo-latin.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,
    U+FEFF,U+FFFD}
@font-face{font-family:"Archivo Black";font-style:normal;font-weight:400;
  font-display:swap;src:url(/assets/fonts/archivo-black-latin.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,
    U+FEFF,U+FFFD}

:root{
  /* brand constants - identical in every theme */
  --orange:#FF563C; --red:#EC3013;
  --black:#201E1D;      /* legacy alias + the pinned ink for orange fields */
  --porcelain:#F3F2F2;  /* legacy alias */

  /* semantic tokens - LIGHT */
  --bg:#F3F2F2; --paper:#FFFFFF; --ink:#201E1D; --ink-soft:#5F5C59;
  --line:#DEDBD6;
  --band:#201E1D; --band-ink:#F3F2F2; --band-soft:#A9A5A1;
  --band-line:#3A3735;

  /* legacy names kept working so nothing outside this file breaks.
     --mute is 4.42:1 on Porcelain and fails AA for normal text (BRAND 8.2):
     it is for rules, borders and large display only. Anything actually READ
     uses --ink-soft (was --mute-text, 5.95:1 light / 7.63:1 dark). */
  --mute:#726F6C;
  --mute-text:var(--ink-soft);

  /* MEASURE, narrowed 2026-08-11 (DESIGN). Was 68ch, which at 17px Archivo is
     680px and lands around 82 characters a line - past the 60-75 that reads
     comfortably, and it was doing it while 40% of the 1120px container sat
     empty to its right. 58ch measures ~590px / ~71 characters. The container
     stays 1120 because headings, grids and the .split aside all use the full
     width; only running prose is narrowed. */
  --maxw:1120px; --measure:58ch;

  /* TEXT-SAFE ACCENT. Soup Orange is 3.16:1 on Porcelain - fine for a large
     display full stop, fails AA for anything read at body size. Where orange
     has to carry a WORD on a light field, this darker cut of the same hue is
     used instead (5.02:1 light). On the dark field orange already clears AA,
     so there it resolves back to orange. Same trick landing.py already uses
     for --ink-accent; hoisted here so the whole site can reach it. */
  --accent-text:#C42A10;
}
[data-theme="light"]{
  --bg:#F3F2F2; --paper:#FFFFFF; --ink:#201E1D; --ink-soft:#5F5C59;
  --line:#DEDBD6;
  --band:#201E1D; --band-ink:#F3F2F2; --band-soft:#A9A5A1;
  --band-line:#3A3735;
}
[data-theme="dark"]{
  --bg:#151413; --paper:#201E1D; --ink:#ECEAE8; --ink-soft:#ABA6A2;
  --line:#35322F;
  --band:#201E1D; --band-ink:#F3F2F2; --band-soft:#A9A5A1;
  --band-line:#3A3735;
  --accent-text:var(--orange);
}
/* System preference, only when the visitor has not chosen "light" by hand.
   Scoped to :root:not([data-theme="light"]) so an explicit choice always
   outranks the OS. */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:#151413; --paper:#201E1D; --ink:#ECEAE8; --ink-soft:#ABA6A2;
    --line:#35322F;
    --band:#201E1D; --band-ink:#F3F2F2; --band-soft:#A9A5A1;
    --band-line:#3A3735;
    --accent-text:var(--orange);
  }
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:Archivo,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;
  font-size:17px;line-height:1.62;font-weight:400;
  -webkit-font-smoothing:antialiased;
}
/* BRAND 8.1: square corners everywhere. The mark has hard corners. */
img,video{max-width:100%;height:auto;display:block;border-radius:0}
h1,h2,h3,h4{margin:0 0 .5em;line-height:1.12;letter-spacing:-.01em;color:var(--ink)}
h1,h2{font-family:"Archivo Black",Archivo,Arial Black,Arial,sans-serif;font-weight:900}
h1{font-size:clamp(2rem,5.2vw,3.5rem);text-transform:uppercase;letter-spacing:-.02em;line-height:1.04}
h2{font-size:clamp(1.5rem,3vw,2.1rem)}
h3,.h3-look{font-family:Archivo,Arial,sans-serif;font-weight:700;font-size:1.16rem;text-transform:none;letter-spacing:-.01em}
p,li{max-width:var(--measure)}
p{margin:0 0 1.1em}
a{color:var(--ink);text-underline-offset:3px;text-decoration-thickness:1px;overflow-wrap:anywhere}
a:hover{text-decoration-thickness:2px}
/* Soup Red focus ring: 3.76:1 on the light field, 4.38:1 on the dark one,
   so it clears the 3:1 non-text minimum in both themes. */
:focus-visible{outline:3px solid var(--red);outline-offset:3px}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 22px}
.skip{position:absolute;left:-9999px;top:0;background:var(--band);color:var(--band-ink);padding:12px 18px;z-index:99}
.skip:focus{left:0}

/* ---- wordmark: right-aligned so the full stop locks under the N ---- */
.mark{display:inline-block;border:2px solid var(--red);padding:6px 10px;text-align:right;
  font-family:"Archivo Black",Archivo,Arial Black,Arial,sans-serif;font-weight:900;
  font-size:12px;line-height:1.16;letter-spacing:.01em;text-transform:uppercase;
  white-space:nowrap;text-decoration:none;color:var(--ink)}
.mark .s{color:var(--orange)}
.mark.on-dark{color:var(--band-ink)}

/* ---- header ---- */
.hdr{background:var(--paper);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:50}
.hdr-in{display:flex;align-items:center;gap:20px;padding:14px 0;flex-wrap:wrap}
.hdr-in .spacer{margin-left:auto}
.nav{display:flex;gap:2px;flex-wrap:wrap;margin-left:auto;align-items:center}
.nav a{font-size:.93rem;font-weight:500;text-decoration:none;padding:8px 11px;color:var(--ink);white-space:nowrap}
@media (max-width:700px){.nav a{font-size:.88rem;padding:12px 9px;min-height:44px;display:flex;align-items:center}.hdr-in{padding:9px 0}.mark{font-size:11px}}
.nav a:hover{background:var(--bg)}
.nav a[aria-current=page]{font-weight:700;box-shadow:inset 0 -3px 0 var(--red)}
.nav a.soon{color:var(--ink-soft);font-size:.86rem}
.call{background:var(--orange);color:var(--black)!important;font-weight:700;padding:11px 16px;
  text-decoration:none;white-space:nowrap;font-size:.97rem;border:2px solid var(--orange)}
/* hover inverts against the CURRENT theme, not against a fixed black - on a
   dark page a black-on-black hover state was invisible. */
.call:hover{background:var(--ink);color:var(--bg)!important;border-color:var(--ink)}

/* ---- theme toggle: a real control, built from the same parts as the rest
   of the system (square, 2px rule, Archivo, uppercase, letterspaced).
   Both labels are always rendered so the control never changes width; the
   inactive one drops to --ink-soft (still AA) and the active one carries the
   same red underscore the current nav item uses, so the state is not
   signalled by colour alone. 44x44 minimum per WCAG 2.5.8. ---- */
.tt{display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;min-width:44px;padding:0 11px;margin-left:6px;
  background:transparent;border:2px solid var(--ink);border-radius:0;
  font-family:Archivo,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;
  font-weight:700;font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;
  line-height:1;cursor:pointer;color:var(--ink)}
.tt span{display:inline-block;padding:3px 0;color:var(--ink-soft)}
.tt .tt-x{padding:0 .45ch}
.tt[aria-pressed="false"] .tt-l,.tt[aria-pressed="true"] .tt-d{
  color:var(--ink);box-shadow:inset 0 -3px 0 var(--red)}
.tt:hover{border-color:var(--red)}
@media (max-width:700px){.tt{margin-left:auto;order:2}}

/* ---- sections ---- */
.dark{background:var(--band);color:var(--band-ink)}
.dark h1,.dark h2,.dark h3{color:var(--band-ink)}
.dark a{color:var(--band-ink)}
.dark .lede{color:var(--band-soft)}
section{padding:64px 0}
section.tight{padding:44px 0}
.rule{border:0;border-top:2px solid var(--red);margin:0}
.lede{font-size:1.22rem;line-height:1.55;max-width:52ch}
.eyebrow{font-size:.72rem;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-soft);
  font-weight:600;margin:0 0 14px}
/* Inside the band, secondary text must resolve against the band, not the
   page field - --ink-soft on the band is 2.50:1 in the light theme. */
.dark .eyebrow,.dark .muted,.dark p.muted,.dark .post-meta,.dark th,
.dark .pkg .meta,.dark form .hint{color:var(--band-soft)}
.dot{color:var(--orange)}
.grid{display:grid;gap:26px;grid-template-columns:repeat(auto-fit,minmax(min(270px,100%),1fr))}
.grid>*{min-width:0}
.grid p,.grid li{max-width:none}
/* A grid that resolves to ONE column is not a grid, it is a full-width box,
   and `.grid p{max-width:none}` was letting its prose run the whole 1076px -
   measured at 1023px, about 120 characters a line, on /work's Datum card. A
   card is a card whatever the column count. (DESIGN, 2026-08-11.) */
.card p,.card li{max-width:62ch}

/* ---- SPLIT: prose left, something real on the right ----------------------
   The container is 1120px and running prose measures under 600px, so every
   text section had roughly 40% of its width doing nothing and no counterweight
   to justify it. This is the counterweight: a named aside column that takes
   evidence, not decoration. Sections that have nothing true to put there keep
   the plain full-width block - an empty right field is better than a padded
   one, and this studio's own /work page is built on refusing to pad. */
.split{display:grid;gap:clamp(28px,4vw,56px);align-items:start;
  grid-template-columns:minmax(0,1fr) minmax(0,var(--aside,400px))}
@media (max-width:900px){.split{grid-template-columns:minmax(0,1fr)}}
.split>.col-a>:last-child{margin-bottom:0}
.split .aside{position:relative}
/* The aside gets the red hairline the cards use, so it reads as part of the
   same system rather than as a floating panel. */
.aside-t{font-size:.72rem;letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink-soft);font-weight:600;margin:0 0 14px;max-width:none}
.dark .aside-t{color:var(--band-soft)}

/* ---- MARK PROOFS ---------------------------------------------------------
   /brand-and-print claims a mark is tested at 32px, in one colour, reversed,
   and wide-and-narrow, and until now it showed none of the four. These are the
   studio's OWN exported marks from /branding, at those exact conditions. The
   claim and the evidence are on the same screen. */
.proof{display:grid;gap:2px;background:var(--line);border:1px solid var(--line)}
.dark .proof{background:var(--band-line);border-color:var(--band-line)}
.proof .pf{background:var(--paper);padding:18px 18px 14px}
.dark .proof .pf{background:var(--bg)}
.proof .pf > img{margin:0 auto}
/* PINNED FIELDS. Three of these four tests are tests of the mark ON PAPER -
   black ink for a stamp or an invoice, and the wide/narrow shapes of a ute door
   and a business card. In the dark theme the mono-ink lockup is #201E1D on
   #151413 and the primary lockup is barely better: the two cells that prove the
   mark survives went blank on a dark screen, which is a worse failure than not
   showing them. So the field is pinned to paper in both themes, because paper
   is what the test is about. The reversed cell keeps its dark ground for the
   same reason - that one IS the dark test. (DESIGN, 2026-08-11.) */
.proof .pf.pf-paper{background:#F3F2F2}
.proof .pf.pf-paper .pf-c{color:#5F5C59}
.proof .pf.pf-paper .favcell .box{background:#FFFFFF;border-color:#DEDBD6}
.proof .pf.pf-paper .favcell span{color:#5F5C59}
.proof .pf.pf-paper .wn .wnb{background:#FFFFFF;border-color:#DEDBD6}
.proof .pf.pf-paper .pal{background:#DEDBD6;border-color:#DEDBD6}
.proof .pf.pf-paper .chip{background:#FFFFFF}
.proof .pf.pf-paper .chip .nm{color:#201E1D}
.proof .pf.pf-paper .chip .hx{color:#5F5C59}
.proof .pf.pf-paper .chip .sw{border-bottom-color:#DEDBD6}
.proof .pf.pf-paper .chip:hover .sw,.proof .pf.pf-paper .chip:focus-visible .sw{box-shadow:inset 0 0 0 3px #201E1D}
.proof .pf.pf-paper .chip::after{background:#201E1D;color:#F3F2F2}
.pf-c{font-size:.72rem;letter-spacing:.11em;text-transform:uppercase;font-weight:700;
  color:var(--ink-soft);margin:14px 0 0;max-width:none;line-height:1.35}
.dark .pf-c{color:var(--band-soft)}
.pf-dark{background:#201E1D!important}
/* the favicon row: real pixel sizes, not a scaled illustration of them */
.favrow{display:flex;gap:20px;align-items:flex-end;flex-wrap:wrap}
.favcell{text-align:center}
.favcell .box{border:1px solid var(--line);display:flex;align-items:center;
  justify-content:center;margin:0 auto 8px;background:var(--bg)}
.dark .favcell .box{border-color:var(--band-line);background:var(--band)}
.favcell span{display:block;font-size:.66rem;letter-spacing:.11em;text-transform:uppercase;
  font-weight:700;color:var(--ink-soft)}
.dark .favcell span{color:var(--band-soft)}
/* wide/narrow: the same lockup forced into a ute door and a business card */
.wn{display:flex;gap:14px;align-items:flex-end;flex-wrap:wrap}
.wn .wnb{max-width:100%}
.wn .wnb{border:1px solid var(--line);padding:10px;display:flex;align-items:center;
  justify-content:center;background:var(--bg)}
.dark .wn .wnb{border-color:var(--band-line);background:var(--band)}

/* ---- PALETTE CHIPS, click to copy ---------------------------------------
   Lifted from the interactive brand guides, where this already exists. It is
   the only interaction on the site that IS the service: a visitor copying a
   hex out of the studio's own palette is using a brand guide, on the page
   that sells brand guides. */
.pal{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2px;
  background:var(--line);border:1px solid var(--line)}
@media (min-width:1100px){.pal{grid-template-columns:repeat(4,minmax(0,1fr))}}
.dark .pal{background:var(--band-line);border-color:var(--band-line)}
.chip{appearance:none;-webkit-appearance:none;border:0;border-radius:0;margin:0;
  font:inherit;text-align:left;cursor:pointer;padding:0;position:relative;
  background:var(--paper);width:100%;
  display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start}
.dark .chip{background:var(--bg)}
.chip .sw{display:block;flex:0 0 62px;height:62px;border-bottom:1px solid var(--line);
  box-shadow:inset 0 0 0 1px rgba(32,30,29,.18)}
.dark .chip .sw{border-bottom-color:var(--band-line)}
.chip .nm{display:block;padding:9px 11px 2px;font-size:.72rem;letter-spacing:.1em;
  text-transform:uppercase;font-weight:700;color:var(--ink)}
.chip .hx{display:block;padding:0 11px 10px;font-size:.78rem;letter-spacing:.04em;
  color:var(--ink-soft);font-variant-numeric:tabular-nums}
.dark .chip .nm{color:var(--band-ink)}
.dark .chip .hx{color:var(--band-soft)}
.chip:hover .sw,.chip:focus-visible .sw{box-shadow:inset 0 0 0 3px var(--ink)}
.chip::after{content:"Copied";position:absolute;left:0;right:0;top:0;height:62px;
  display:flex;align-items:center;justify-content:center;
  font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;font-weight:700;
  background:var(--ink);color:var(--bg);opacity:0;pointer-events:none;
  transition:opacity .15s}
.chip.copied::after{opacity:1}
.chip .cn{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

/* ---- FILMSTRIP: the landing page's flyover, held still ------------------
   /work needed to show the one thing the studio has actually built that a
   prospect can judge as craft, and the flyover is scroll-driven - it cannot be
   shown by standing still on it. So: four frames, at the four moments the real
   page passes through, drawn out of the SAME parts the real page is drawn out
   of (plate, chrome, url bar with its progress fill, a six-box body, the phone
   coming over the corner). Not a screenshot - a screenshot is a picture of a
   thing, and this page's whole argument is the difference between the two.

   CSS only, no images, no script. About 1.6KB, and it is inert: nothing here
   animates, so prefers-reduced-motion has nothing to switch off. */
.film{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:34px 26px;
  padding-right:12px}
@media (max-width:430px){.film{grid-template-columns:minmax(0,1fr)}}
.fr .pl{position:relative;aspect-ratio:16/10;border:2px solid var(--mute);
  background:var(--paper);display:flex;flex-direction:column;overflow:visible}
.dark .fr .pl{background:var(--band);border-color:var(--band-soft)}
.fr .cr{display:flex;align-items:center;gap:5px;padding:5px 6px;
  border-bottom:2px solid var(--mute);flex:0 0 auto}
.dark .fr .cr{border-bottom-color:var(--band-soft)}
.fr .ub{flex:1 1 auto;height:9px;border:1px solid var(--line);background:var(--bg);
  position:relative}
.dark .fr .ub{border-color:var(--band-line);background:var(--deep,#151413)}
.fr .ub b{position:absolute;left:1px;top:1px;bottom:1px;background:var(--orange);
  width:calc(100% - 2px);transform:scaleX(var(--p,0));transform-origin:left}
.fr .pc{flex:0 0 auto;font-family:"Archivo Black",Archivo,Arial Black,sans-serif;
  font-weight:900;font-size:8px;letter-spacing:.08em;color:var(--accent-text)}
.fr .nb{flex:0 0 auto;display:flex;gap:3px}
.fr .nb i{display:block;width:9px;height:4px;background:var(--ink)}
.dark .fr .nb i{background:var(--band-ink)}
.fr .bd{flex:1 1 auto;min-height:0;display:grid;gap:4px;padding:6px;
  grid-template-columns:repeat(3,minmax(0,1fr));grid-template-rows:.6fr 1fr 1fr}
.fr .bd i{display:block;border:1px dashed var(--line);background:transparent}
.dark .fr .bd i{border-color:var(--band-line)}
.fr .bd i.hh{grid-column:span 3}
.fr .bd i.on{border-style:solid;border-color:var(--mute);background:var(--bg)}
.dark .fr .bd i.on{border-color:var(--band-soft);background:var(--band-line)}
.fr .bd i.lit{border-color:var(--red);box-shadow:inset 0 0 0 1px var(--red)}
/* the enquiry card of station 01, and the price panel of station 03 - the two
   overlays the real page floats above the plate */
.fr .ov{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  background:var(--paper);border:2px solid var(--red);padding:7px 9px;
  display:flex;flex-direction:column;gap:4px;z-index:2}
.dark .fr .ov{background:var(--band)}
.fr .ov.wide{width:78%}
.fr .ov u{display:block;height:5px;background:var(--line);text-decoration:none}
.dark .fr .ov u{background:var(--band-line)}
.fr .ov u.sh{width:52%}
.fr .ov em{font-style:normal;font-family:"Archivo Black",Archivo,Arial Black,sans-serif;
  font-weight:900;font-size:9px;letter-spacing:.04em;color:var(--accent-text);
  display:flex;justify-content:space-between;gap:8px}
.fr .ov em s{text-decoration:none;color:var(--ink-soft);font-family:Archivo,Arial,sans-serif;
  font-weight:700;letter-spacing:.12em}
.dark .fr .ov em s{color:var(--band-soft)}
/* the phone, over the bottom-right corner, exactly as it comes in at 05 */
.fr .fp{position:absolute;right:-6%;bottom:-8%;width:16%;aspect-ratio:9/17;z-index:3;
  border:2px solid var(--red);background:var(--paper);
  display:flex;flex-direction:column;gap:2px;padding:3px 2px}
.dark .fr .fp{background:var(--band)}
.fr .fp s{display:block;background:var(--line);text-decoration:none;flex:0 0 auto;height:14%}
.dark .fr .fp s{background:var(--band-line)}
.fr .fp s.t{background:var(--red);height:9%}
.fr .fp s.g{flex:1 1 auto}
.fr figcaption{font-family:"Archivo Black",Archivo,Arial Black,sans-serif;font-weight:900;
  font-size:.66rem;letter-spacing:.14em;text-transform:uppercase;color:var(--ink);
  margin:26px 0 0;display:flex;align-items:center;gap:8px}
.dark .fr figcaption{color:var(--band-ink)}
.fr figcaption::before{content:"";flex:0 0 auto;width:16px;height:3px;background:var(--red)}
.fr{margin:0}

/* ---- cards: border-led, never fill-led (survives forced dark) ---- */
.card p.muted,p.muted{color:var(--ink-soft)}
.card{background:var(--paper);border:1px solid var(--line);border-left:4px solid var(--red);padding:24px}
.dark .card{background:transparent;border-color:var(--band-line);border-left-color:var(--red)}
.card h3{margin-bottom:.35em}
.card p:last-child{margin-bottom:0}

.pkg{background:var(--paper);border:1px solid var(--line);border-top:5px solid var(--red);padding:28px;
  display:flex;flex-direction:column}
.pkg .price{font-family:"Archivo Black",Archivo,Arial Black,sans-serif;font-weight:900;
  font-size:2.5rem;line-height:1;margin:.15em 0 .1em;color:var(--ink)}
.pkg .meta{color:var(--ink-soft);font-size:.95rem;margin:0 0 16px}
.pkg ul{margin:0 0 20px;padding:0;list-style:none}
.pkg li{position:relative;padding-left:20px;margin-bottom:8px;font-size:.97rem;line-height:1.5}
.pkg li::before{content:"";position:absolute;left:0;top:.62em;width:9px;height:2px;background:var(--red)}
.pkg .btn{margin-top:auto}

/* .dark a (0,1,1) outranks .btn (0,1,0), which silently put Porcelain text on
   Soup Orange = 2.79:1 and fails AA. BRAND 8.2 forbids it. Pinned here. */
.dark a.btn,.dark a.call{color:var(--black)}
.dark a.btn.ghost{color:var(--band-ink)}
.dark a.btn.ghost:hover{color:var(--band)}
.btn{display:inline-block;background:var(--orange);color:var(--black);font-weight:700;
  padding:14px 22px;text-decoration:none;border:2px solid var(--orange);text-align:center}
.btn:hover{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.btn.ghost{background:transparent;border-color:var(--ink);color:var(--ink)}
.btn.ghost:hover{background:var(--ink);color:var(--bg)}
.dark .btn.ghost{border-color:var(--band-ink);color:var(--band-ink)}
.dark .btn.ghost:hover{background:var(--band-ink);color:var(--band)}
/* On the band, hover has to invert against the BAND. Higher specificity than
   the .dark a.btn colour pin above, which is what a hover state needs to be
   allowed to move at all - without this the button hovered to black-on-black. */
.dark a.btn:hover,.dark a.call:hover{background:var(--band-ink);color:var(--band);border-color:var(--band-ink)}

table{border-collapse:collapse;width:100%;font-size:.97rem;margin:0 0 1.2em}
th,td{text-align:left;padding:11px 12px;border-bottom:1px solid var(--line);vertical-align:top}
th{font-weight:700;font-size:.78rem;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-soft)}
td:last-child,th:last-child{text-align:right;white-space:nowrap}
.dark th,.dark td{border-bottom-color:var(--band-line)}
@media (max-width:520px){td:last-child,th:last-child{white-space:normal}}

.suburbs{columns:3 165px;column-gap:26px;padding:0;list-style:none;margin:0}
.suburbs li{padding:5px 0;font-size:.97rem;border-bottom:1px solid var(--line);break-inside:avoid}
.dark .suburbs li{border-bottom-color:var(--band-line)}

/* honest labelling - BRAND 8.5 */
.tag{display:inline-block;font-size:.68rem;letter-spacing:.13em;text-transform:uppercase;
  font-weight:700;padding:5px 9px;border:1px solid var(--ink);margin-bottom:12px}
.tag.demo{border-color:var(--ink-soft);color:var(--ink-soft)}
.dark .tag{border-color:var(--band-ink)}
.dark .tag.demo{border-color:var(--band-soft);color:var(--band-soft)}

form label{display:block;font-weight:600;margin:0 0 6px;font-size:.95rem}
form input,form select,form textarea{width:100%;padding:13px 14px;border:1px solid var(--ink);
  background:var(--paper);font:inherit;font-size:16px;color:var(--ink);border-radius:0;margin-bottom:18px}
form textarea{min-height:130px;resize:vertical}
form .hint{color:var(--ink-soft);font-size:.87rem;margin:-13px 0 18px;max-width:none}
fieldset{border:0;padding:0;margin:0}

.notes-list{list-style:none;padding:0;margin:0}
.notes-list li{border-bottom:1px solid var(--line);padding:26px 0;max-width:none}
.notes-list h2,.notes-list h3{font-family:"Archivo Black",Archivo,Arial Black,sans-serif;font-weight:900;font-size:1.32rem;margin-bottom:.3em}
.notes-list a{text-decoration:none}
.notes-list a:hover h2{box-shadow:inset 0 -3px 0 var(--orange)}
.post-meta{color:var(--ink-soft);font-size:.87rem;margin:0 0 4px}

article.post{max-width:var(--measure)}
article.post h2{font-size:1.5rem;margin-top:1.9em}
article.post h3{margin-top:1.5em}
article.post ul,article.post ol{padding-left:22px}
article.post li{margin-bottom:.5em}
article.post strong{font-weight:700}

.ftr{background:var(--band);color:var(--band-ink);padding:52px 0 34px}
.ftr h2{font-family:"Archivo Black",Archivo,Arial Black,sans-serif;font-weight:900;
  font-size:.78rem;letter-spacing:.14em;text-transform:uppercase;color:var(--band-soft);margin:0 0 14px}
.ftr a{color:var(--band-ink);text-decoration:none}
.ftr a:hover{text-decoration:underline}
.ftr ul{list-style:none;padding:0;margin:0}
.ftr li{margin-bottom:4px;font-size:.95rem;max-width:none;overflow-wrap:anywhere}
/* WCAG 2.5.8: 17px text alone gives a 17px hit area. Pad to >=28px. */
.ftr li a{display:inline-block;padding:6px 0}
/* SOCIAL TILES. Square, bordered, the same hard-edged vocabulary as the
   buttons and the mark - not circles, which would be the only round thing
   on the site. 40px is above the 24px minimum touch target with room. */
.socs{display:flex;flex-wrap:wrap;gap:10px;margin:18px 0 20px}
.soc{display:flex;align-items:center;justify-content:center;width:42px;height:42px;
  border:2px solid currentColor;color:inherit;transition:background .18s,color .18s}
.soc svg{width:19px;height:19px;fill:currentColor;display:block}
.soc:hover,.soc:focus-visible{background:var(--orange);color:var(--black);
  border-color:var(--orange)}
@media (max-width:520px){.socs{gap:8px}.soc{width:44px;height:44px}}

.ftr .legal{border-top:1px solid var(--band-line);margin-top:38px;padding-top:24px;color:var(--band-soft);font-size:.85rem}
.ftr .legal a{display:inline-block;padding:7px 0}
.ftr .legal p{max-width:none;margin:0 0 5px}
.nowrap{white-space:nowrap}
/* Mobile: the wrapped nav made the sticky header eat a third of a 375px
   viewport. Header goes static and the call moves to a thumb-reachable
   fixed bar - tap-to-call is the highest-value element on a trades site.

   MEASURED AGAIN 2026-08-11 (DESIGN): it was still 172px tall at 390px - the
   mark on row one, then SEVEN nav links wrapping across rows two and three,
   with the theme toggle pushed to the far right of row three. A fifth of the
   first screen was navigation before a word of the page appeared. The nav is
   now ONE row that scrolls sideways, and the theme toggle moves up beside the
   mark, which is where a control belongs rather than at the end of a list of
   destinations. 172px -> ~112px, and nothing was removed.

   Why a scroller and not a hamburger: a hamburger is a button, a panel, a
   focus trap and an escape key - real work, and it hides every destination
   behind a tap. The scroller keeps the first four visible, and the fifth is
   deliberately cut by the viewport edge so the row reads as continuing. */
/* Demonstration-guide cards on /work, added 2026-08-21 (site review, section 02).
   The tile is a palette card generated from each guide's own colours, not a
   screenshot, and says so in its alt text. The cards are not links yet: the
   guides go public when build.py's PUBLISH_GUIDES flips (see the note there). */
.guides .guide{display:block;text-decoration:none;color:inherit;padding:0;overflow:hidden}
.guides .guide p{margin-bottom:22px}
.guides .guide img{display:block;width:100%;height:auto;border-bottom:2px solid var(--ink)}
.guides .guide .tag,.guides .guide h3,.guides .guide p,.guides .guide .more{margin-left:22px;margin-right:22px}
.guides .guide .tag{display:inline-block;margin-top:18px}
.guides .guide .more{display:block;margin-top:6px;margin-bottom:22px;font-weight:700;color:var(--red)}
.guides .guide:hover .more{text-decoration:underline}
.callbar{display:none}
@media (max-width:700px){
  section{padding:46px 0}
  .nav{width:100%;margin-left:0;order:3;flex-wrap:nowrap;overflow-x:auto;
       -webkit-overflow-scrolling:touch;scrollbar-width:none;
       /* full-bleed out of .wrap's 22px gutter so the cut edge sits on the
          screen edge, which is what makes it read as scrollable */
       margin-left:-22px;margin-right:-22px;padding:0 22px;
       scroll-padding-left:22px;
       -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 34px),transparent);
       mask-image:linear-gradient(90deg,#000 calc(100% - 34px),transparent)}
  .nav::-webkit-scrollbar{display:none}
  .nav a{flex:0 0 auto}
  .hdr-in{gap:12px}
  .suburbs{columns:2 130px}
  .hdr{position:static}
  .hdr .call{display:none}
  body{padding-bottom:66px}
  .callbar{display:block;position:fixed;left:0;right:0;bottom:0;z-index:60;
    background:var(--orange);border-top:2px solid var(--black)}
  .callbar a{display:block;padding:17px 16px;text-align:center;text-decoration:none;
    color:var(--black);font-weight:700;font-size:1.06rem}
  .ftr{padding-bottom:22px}
}
@supports(padding:env(safe-area-inset-bottom)){
  @media (max-width:700px){
    .callbar a{padding-bottom:calc(17px + env(safe-area-inset-bottom))}
    body{padding-bottom:calc(66px + env(safe-area-inset-bottom))}
  }
}
/* Nothing theme-dependent is transitioned or animated, so switching theme is
   an instant repaint. This rule stays as the global backstop. */
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* PRINT: force the light token set. A dark-themed page must never print as a
   black rectangle. :root:root is doubled deliberately - it gives (0,2,0),
   matching the prefers-color-scheme block above, and it sits later in the
   source, so it wins even when the OS is in dark mode at print time. */
@media print{
  :root:root{
    --bg:#F3F2F2; --paper:#FFFFFF; --ink:#201E1D; --ink-soft:#5F5C59;
    --line:#DEDBD6;
    --band:#201E1D; --band-ink:#F3F2F2; --band-soft:#A9A5A1;
    --band-line:#3A3735;
  }
  body{background:#FFFFFF;padding-bottom:0}
  /* A printer with background graphics OFF - the common default - drops the
     band fill and leaves Porcelain text on white paper at about 1.1:1, i.e.
     invisible. VISUAL-QA caught it on /home. In print the bands stop being
     bands: dark ink on paper, with a red rule to keep the section break. */
  .dark,.ftr,.mini{background:#FFFFFF!important;color:#201E1D!important;
    border-top:2px solid #EC3013}
  .dark h1,.dark h2,.dark h3,.dark a,.dark .lede,.dark .eyebrow,
  .ftr a,.ftr h2,.ftr .legal,.mini p,.mini a{color:#201E1D!important}
  .btn,.call{background:#FFFFFF!important;color:#201E1D!important;border:2px solid #201E1D}
  .hdr{position:static}
  .skip,.callbar,.tt{display:none!important}
  a{text-decoration:underline}
}