/* ============================================================================
   Tbay Tech Guy
   ----------------------------------------------------------------------------
   Design decisions, so future edits stay deliberate:

   DIRECTION   Low-resolution pixel art, committed to end to end. The service
               illustrations were always pixel art; now the page they sit on is
               built the same way — a 4px pixel grid, hard edges, no blur, no
               anti-aliased corners, no in-between states. It reads like a
               repair shop rendered on a machine with 16 colours.

   GRID        One unit: 4px. Every border, offset, shadow, notch and icon is a
               whole number of units. Nothing lands on a half pixel.

   EDGES       Radius is 0 everywhere. Corners are stepped with 4px notches
               painted in the page colour, which is how a pixel artist draws a
               rounded box. Borders are 2px, never hairlines.

   DEPTH       Hard offset shadows only (4px 4px 0). No blur radius appears
               anywhere in this file. Depth comes from displacement, the way a
               sprite drops a shadow onto a tile.

   COLOUR      Sleeping Giant basalt, boreal spruce and sunrise copper lead.
               Amethyst and rust remain quiet wayfinding accents. Gradients are
               replaced by dither: a 4px checkerboard doing the job a soft
               gradient used to do, which is the period-correct solution.

   ART         Three hand-built SVGs — harbour sunrise, grain elevators, aurora
               — all drawn on an integer grid with shape-rendering:crispEdges
               and staircase silhouettes. No curves, no gradients, no filters.
               The sunrise is the hero itself, full bleed, with a stepped
               dither scrim and scanlines over it rather than a soft overlay.

   TYPE        Two bitmap faces and one text face, split strictly by job.
               Silkscreen has the arcade weight but only small-caps lowercase
               and tight apertures, so it keeps the big headings, the prices
               and the step numbers, where size carries it.
               Jersey 15 has true lowercase and digits that cannot be confused
               (5 is not S, C is not O), so it takes every label, chip, card
               title and table cell — the text you actually have to read at
               14–16px. Both render with anti-aliasing off.
               Chivo stays for body copy: paragraphs in a bitmap font are a
               legibility tax the reader did not agree to pay.

   MOTION      steps() timing, never ease. A pixel interface does not have
               intermediate frames. Buttons displace along the grid instead of
               fading. prefers-reduced-motion honoured.
   ========================================================================== */

:root {
  /* --- surfaces: ink, ticket paper and weathered metal --- */
  --stone-900: #172025;   /* ink */
  --stone-800: #293236;
  --stone-600: #535C5B;
  --stone-500: #727A77;
  --stone-400: #989D97;
  --stone-300: #C3C4BA;
  --stone-200: #D6D4C9;   /* rules */
  --stone-150: #E5E1D6;
  --stone-100: #EFEEE7;   /* canvas */
  --stone-050: #F8F5ED;   /* plates */
  --paper:     #FFFCF5;
  --paper-deep:#E8E3D8;

  /* --- the Thunder Bay palette ---------------------------------------
     Every hue below is sampled from something you can go and look at.
     Nothing here is a framework swatch.

       amethyst  the mineral, mined at East Loon Road and nowhere else
                 on earth in commercial quantity. Muted, hematite-tinted.
       superior  Lake Superior off the breakwall in November.
       harbour   the same water in the shallows.
       ice       hoarfrost on the Marina rail in January.
       ember     the sun coming up behind the Giant.
       rose      the band of sky just above it.
       spruce    boreal forest north of the expressway.
       rust      the grain elevators and the lakers tied up beneath them.
       aurora    what you drive out past Hazelwood to see.

     Sixteen-ish colours, which is roughly the budget a low-res sprite
     sheet gets, and the reason the page holds together.
     ------------------------------------------------------------------ */
  --amethyst:      #71487A;  /* unslop-ignore — the mineral, a stated choice */
  --amethyst-deep: #4B2E53;  /* unslop-ignore */
  --amethyst-wash: #EBE3ED;  /* unslop-ignore */

  /* Basalt and boreal spruce replace the previous navy foundation. */
  --night:    #181C18;
  --superior: #27322B;
  --harbour:  #4F7565;
  --ice:      #E0E5DC;
  --ice-dim:  #AAB5A9;

  --ember: #D47A3C;
  --rose:  #9E5D62;
  --spruce:#536A57;
  --rust:  #A4532E;
  --aurora:#397468;

  /* --------------------------------------------------------------------
     Category tones. Colour on this page is never decoration — each group
     of services owns a hue, and that hue drives the chip, the group rule,
     the illustration plate and the accent strokes inside it. Scanning for
     "the green ones" is a real navigation shortcut on a list this long.
     -------------------------------------------------------------------- */
  --tone: var(--amethyst);
  --tone-wash: var(--amethyst-wash);

  /* ---- the pixel grid ------------------------------------------------
     --u is the pixel. Everything structural is a multiple of it, so the
     page keeps the same resolution as the sprites sitting on it. --bw is
     the stroke width: 2px, half a unit, the thinnest line that still
     looks drawn rather than hinted.
     ------------------------------------------------------------------ */
  --u:  4px;
  --u2: 8px;
  --bw: 2px;
  --r-1: 0;
  --r-2: 0;

  /* hard shadows. No blur value appears in this file on purpose. */
  --drop:      var(--u) var(--u) 0 rgba(23, 32, 37, .22);
  --drop-lift: 6px 6px 0 rgba(23, 32, 37, .26);
  --drop-ink:  var(--u) var(--u) 0 var(--stone-900);
  --drop-deep: 6px 6px 0 rgba(5, 15, 19, .55);

  /* the dither: a 4px checkerboard, standing in for every gradient this
     page used to have. Tinted per surface via --dither-ink. */
  --dither-ink: rgba(23, 32, 37, .05);

  --sans: "Chivo", ui-sans-serif, "Segoe UI", Helvetica, sans-serif;
  /* --disp is the loud one, --mono the readable one, --num the one that has
     to be right: prices go in Silkscreen because its digits are unmistakable
     at size, everything wordy goes in Jersey 15 because its lowercase is. */
  --disp: "Silkscreen", "Chivo", ui-sans-serif, sans-serif;
  --mono: "Jersey 15", ui-monospace, "SFMono-Regular", Consolas, monospace;
  --num:  "Silkscreen", "Jersey 15", ui-monospace, monospace;

  /* ---- the type ladder -----------------------------------------------
     Every size on the page comes from this ladder. Each step is
     clamp(phone, fluid, large monitor), written in rem rather than px,
     which fixes the two things fixed px got wrong:

       - rem means a reader who has raised their browser font size
         actually gets larger text. px ignored that setting outright.
       - the fluid middle term means a 27" monitor is given a page scaled
         to it, instead of the same 16px ribbon a phone gets.

     The 4px grid does NOT scale. --u stays 4px at every width, because
     the sprites, the corner notches and the hard shadows are all drawn
     on it, and a 4.7px pixel is not a pixel. Type breathes, grid does not.
     ------------------------------------------------------------------ */
  --t-3xs: clamp(0.8125rem, 0.79rem + 0.10vw, 0.9375rem); /* 13 → 15 */
  --t-2xs: clamp(0.875rem,  0.85rem + 0.12vw, 1rem);      /* 14 → 16 */
  --t-xs:  clamp(0.9375rem, 0.90rem + 0.16vw, 1.0625rem); /* 15 → 17 */
  --t-sm:  clamp(1rem,      0.96rem + 0.19vw, 1.1875rem); /* 16 → 19 */
  --t-md:  clamp(1.0625rem, 1.01rem + 0.26vw, 1.3125rem); /* 17 → 21 */
  --t-lg:  clamp(1.1875rem, 1.11rem + 0.36vw, 1.5rem);    /* 19 → 24 */
  --t-xl:  clamp(1.375rem,  1.25rem + 0.55vw, 1.875rem);  /* 22 → 30 */
  --t-2xl: clamp(1.5rem,    1.29rem + 0.94vw, 2.375rem);  /* 24 → 38 */
  --t-3xl: clamp(1.625rem,  1.29rem + 1.50vw, 3rem);      /* 26 → 48 */
  --t-num: clamp(1.75rem,   1.55rem + 0.88vw, 2.5rem);    /* 28 → 40 */

  /* one spacing scale, every step a whole number of pixel units */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px; --s8: 72px; --s9: 112px;

  --gut: clamp(20px, 4vw, 72px);
  /* the measure grows with the monitor instead of parking at 1320px and
     leaving a 27" display as two empty fields with a strip down the middle */
  --max: clamp(1320px, 84vw, 1680px);

  /* ---- the one gutter formula ----------------------------------------
     Every full-bleed section starts its content here, and every boxed one
     is pushed in by the same amount, so the left edge of the page is a
     single line from the header to the footer.

     Note the 100%, not 100vw. 100vw includes the scrollbar, 100% does
     not, and mixing the two is what used to leave the promise strip
     sitting seven pixels off every other section on a desktop browser.
     ------------------------------------------------------------------ */
  --edge: max(var(--gut), calc((100% - var(--max)) / 2 + var(--gut)));

  --bar-h: 72px;
}

/* Silkscreen and Jersey 15 are bitmap faces rendered with smoothing off, so
   a fractional size drops stems onto half pixels and the letterforms go
   furry. Where the browser can do the arithmetic, snap the whole ladder to
   whole pixels first — the same rule the rest of the page follows. */
@supports (font-size: round(1px, 1px)) {
  :root {
    --t-3xs: round(clamp(0.8125rem, 0.79rem + 0.10vw, 0.9375rem), 1px);
    --t-2xs: round(clamp(0.875rem,  0.85rem + 0.12vw, 1rem), 1px);
    --t-xs:  round(clamp(0.9375rem, 0.90rem + 0.16vw, 1.0625rem), 1px);
    --t-sm:  round(clamp(1rem,      0.96rem + 0.19vw, 1.1875rem), 1px);
    --t-md:  round(clamp(1.0625rem, 1.01rem + 0.26vw, 1.3125rem), 1px);
    --t-lg:  round(clamp(1.1875rem, 1.11rem + 0.36vw, 1.5rem), 1px);
    --t-xl:  round(clamp(1.375rem,  1.25rem + 0.55vw, 1.875rem), 1px);
    --t-2xl: round(clamp(1.5rem,    1.29rem + 0.94vw, 2.375rem), 1px);
    --t-3xl: round(clamp(1.625rem,  1.29rem + 1.50vw, 3rem), 1px);
    --t-num: round(clamp(1.75rem,   1.55rem + 0.88vw, 2.5rem), 1px);
  }
}

/* ---------------------------------------------------------------- reset */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  /* dither, not gradient: 4px checkerboard over flat canvas */
  background:
    repeating-conic-gradient(var(--dither-ink) 0% 25%, transparent 0% 50%)
      0 0 / var(--u) var(--u),
    var(--stone-100);
  color: var(--stone-900);
  font: 400 var(--t-sm)/1.65 var(--sans);
  font-feature-settings: "kern" 1;
  -webkit-font-smoothing: antialiased;
  /* nothing on this page is allowed to push the page sideways on a phone */
  overflow-x: hidden;
}
/* bitmap type: never smoothed, never tracked-in, and given room to breathe
   because Silkscreen has no descender clearance to spare */
h1, h2, h3, h4 {
  font-family: var(--disp);
  font-weight: 700;
  line-height: 1.45;
  letter-spacing: 0;
  margin: 0;
}
/* Anti-aliasing a bitmap face just smears it. Everything set in Silkscreen
   asks the renderer to leave the edges alone. */
h1, h2, h3, h4,
.eyebrow, .btn, .chip, .skip,
.bar__mark, .bar__nav a,
.strip__k, .group__h, .filters__status,
.service-search, .filter-select,
.p, .p__to, .p__unit, .p__compare, .svc__meta,
.steps__n, .menu::before,
.ct__row--head, .ct__was, .ct__now,
.area__list li, .hours dd, .foot strong {
  -webkit-font-smoothing: none;
  -moz-osx-font-smoothing: unset;
  font-smooth: never;
}

p { margin: 0; }
ul, ol, dl { margin: 0; padding: 0; list-style: none; }
a { color: inherit; }
img, svg { display: block; max-width: 100%; }
/* the whole point: no resampling, ever */
img { image-rendering: pixelated; }
svg { shape-rendering: crispEdges; }
button { font: inherit; color: inherit; }
/* the header is sticky, so anchor jumps need to clear it */
section[id] { scroll-margin-top: calc(var(--bar-h) + var(--s4)); }

::selection { background: var(--ember); color: var(--night); }

/* Rust rather than ember: ember is only 2.4:1 against the paper surfaces,
   so a focused chip on the price board had a ring you could lose. Rust
   clears 3:1 against both the paper and the night, which is the one colour
   on the palette that can be the focus ring everywhere. */
:focus-visible {
  outline: var(--u) solid var(--rust);
  outline-offset: var(--bw);
  border-radius: 0;
}

/* a label that a screen reader reads and a phone screen does not spend
   40% of its width on */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 99;
  background: var(--stone-900); color: var(--paper);
  padding: var(--s3) var(--s4);
  font: 400 var(--t-xs)/1 var(--mono);
  min-height: 44px; display: inline-flex; align-items: center;
  border: var(--bw) solid var(--ember);
}
.skip:focus { left: var(--s3); top: var(--s3); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* --------------------------------------------------------- pixel corners
   A stepped corner is how you draw a rounded box at this resolution: cut a
   single pixel out of each corner. Painting the page colour over the corner
   does it without clip-path, which would eat the hard shadow. --notch is set
   per surface to whatever sits behind it. */
.svc::after,
.strip::after,
.filterbar::after,
.area::after,
.compare__table::after {
  content: "";
  position: absolute;
  inset: calc(var(--bw) * -1);
  z-index: 3;
  pointer-events: none;
  background-image:
    linear-gradient(var(--notch, var(--stone-100)) 0 0),
    linear-gradient(var(--notch, var(--stone-100)) 0 0),
    linear-gradient(var(--notch, var(--stone-100)) 0 0),
    linear-gradient(var(--notch, var(--stone-100)) 0 0);
  background-size: var(--u) var(--u);
  background-position: 0 0, 100% 0, 0 100%, 100% 100%;
  background-repeat: no-repeat;
}

/* ---------------------------------------------------------- shared bits */
.eyebrow {
  font: 400 var(--t-xs)/1.3 var(--mono);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--stone-600);
  margin-bottom: var(--s4);
}
.eyebrow--light { color: var(--stone-300); }

/* Buttons are sprites: two pixels of border, a four pixel drop, and on press
   they travel down the grid until the shadow is gone. No fade, no scale. */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s2);
  min-height: 48px;
  padding: 12px 20px;
  border: var(--bw) solid var(--stone-900);
  border-radius: 0;
  background: var(--paper);
  color: var(--stone-900);
  font: 400 var(--t-md)/1.2 var(--mono);
  letter-spacing: .02em;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--drop-ink);
  transition:
    transform .08s steps(2, end),
    box-shadow .08s steps(2, end),
    background-color .08s steps(2, end),
    color .08s steps(2, end);
}
.btn:hover { transform: translate(2px, 2px); box-shadow: 2px 2px 0 var(--stone-900); }
.btn:active { transform: translate(var(--u), var(--u)); box-shadow: 0 0 0 var(--stone-900); }
.btn--solid { background: var(--stone-900); color: var(--stone-050); }
.btn--solid:hover { background: var(--harbour); }
.btn--light { background: var(--paper); color: var(--stone-900); }
.btn--light:hover { background: var(--amethyst); color: var(--paper); }
.btn--ghost {
  background: transparent;
  border-color: var(--ice);
  color: var(--ice);
  box-shadow: var(--u) var(--u) 0 rgba(224, 229, 220, .28);
}
.btn--ghost:hover {
  background: var(--ice); color: var(--superior);
  box-shadow: 2px 2px 0 rgba(224, 229, 220, .28);
}

/* ------------------------------------------------------- the tone map */
[data-tone="quick"]   { --tone: #315F68; --tone-wash: #DCE8E7; }
[data-tone="phone"]   { --tone: #76546F; --tone-wash: #E9E0E6; } /* amethyst */
[data-tone="laptop"]  { --tone: #35636B; --tone-wash: #D9E6E5; } /* superior */
[data-tone="desktop"] { --tone: #945534; --tone-wash: #EEE0D5; } /* rust     */
[data-tone="cooling"] { --tone: #477268; --tone-wash: #DBE7E1; } /* aurora   */
[data-tone="build"]   { --tone: #99642F; --tone-wash: #F0E2CE; } /* ember    */
[data-tone="onsite"]  { --tone: #59694E; --tone-wash: #E0E5D9; } /* spruce   */

/* ---------------------------------------------------------------- header */
/* The bar is the status bar of the machine: flat night, no blur, and a
   dashed ember rule under it drawn as 4px on, 4px off. */
.bar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: var(--s5);
  /* pinned, because the sticky filter bar below parks at exactly --bar-h
     and a header that grows with its contents would leave a gap or an
     overlap at some width nobody thought to test */
  height: var(--bar-h);
  padding: 0 var(--gut);
  background: var(--night);
  color: var(--ice);
  border-bottom: var(--bw) solid transparent;
  border-image: repeating-linear-gradient(
    90deg,
    var(--ember) 0 var(--u),
    rgba(224, 229, 220, .18) var(--u) var(--u2)
  ) 2;
}
.bar__mark {
  display: flex; align-items: center; gap: 10px;
  min-height: 44px;
  font: 400 var(--t-xs)/1 var(--disp);
  letter-spacing: 0;
  text-decoration: none; margin-right: auto; color: #F1F5F4;
}
.bar__glyph { width: 32px; height: 24px; flex: none; }
.bar__nav { display: flex; gap: var(--s5); font: 400 var(--t-xs)/1 var(--mono); }
.bar__nav a {
  display: flex; align-items: center;
  min-height: 44px;
  text-decoration: none; color: var(--ice-dim);
  border-bottom: var(--bw) solid transparent;
  transition: color .08s steps(2, end), border-color .08s steps(2, end);
}
.bar__nav a:hover { color: #F1F5F4; border-bottom-color: var(--ember); }
.bar__cta {
  padding: 10px 16px;
  font-size: var(--t-xs);
  min-height: 44px;
  background: var(--ember); border-color: var(--night); color: var(--night);
  box-shadow: var(--u) var(--u) 0 #7A3F18;
}
.bar__cta:hover { background: #E08D3F; color: var(--night); box-shadow: 2px 2px 0 #7A3F18; }
.bar__cta:active { box-shadow: 0 0 0 #7A3F18; }

/* the nav goes before the wordmark does — four links need more room than
   they have once the CTA is a proper 44px target */
@media (max-width: 1000px) { .bar__nav { display: none; } }
@media (max-width: 400px) {
  .bar { gap: var(--s3); padding: 0 var(--s4); }
  .bar__mark { gap: var(--s2); }
  .bar__mark span { font-size: 13px; }
  .bar__cta { padding: 10px 12px; }
}

/* ------------------------------------------------------------------ hero */
/* The sunrise is the hero — full bleed, edge to edge, sized to the viewport.
   Everything laid over it is a period-correct effect rather than a modern
   one: the copy is made legible by a stepped dither scrim (three discrete
   densities with hard edges, the way a sprite fades out on hardware that has
   no alpha channel), the scene carries CRT scanlines, and the only motion is
   stars blinking and the sun's road drifting a pixel at a time. */
.hero {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  min-height: clamp(560px, 88svh, 900px);
  background: var(--night);
  color: var(--ice);
  overflow: hidden;

  /* ---- one number the copy and the scrim both read ------------------
     The old version sized the copy in ch and the scrim in percent of the
     viewport, so the two drifted apart as the window changed: at 785px
     wide a hundred pixels of headline sat on bare sunrise with no scrim
     under it at all. Both now derive from --hero-end, so the ramp starts
     where the text stops, at every width, by construction.
     ---------------------------------------------------------------- */
  --hero-copy: 620px;
  --hero-end: min(
    calc(var(--edge) + var(--hero-copy)),
    calc(100% - var(--gut))
  );
  --hero-ramp: clamp(48px, 7%, 132px);
}
/* the scrim. Mask stops are hard, so the ramp is four visible steps —
   a deliberate posterised edge, not a gradient pretending to be one. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background:
    repeating-conic-gradient(#070B07 0% 25%, transparent 0% 50%)
      0 0 / var(--u) var(--u),
    repeating-conic-gradient(#070B07 0% 25%, transparent 0% 50%)
      2px 2px / var(--u) var(--u);
  -webkit-mask-image: linear-gradient(
    90deg,
    #000 0 var(--hero-end),
    rgba(0, 0, 0, .58) var(--hero-end) calc(var(--hero-end) + var(--hero-ramp) * 1),
    rgba(0, 0, 0, .30) calc(var(--hero-end) + var(--hero-ramp) * 1) calc(var(--hero-end) + var(--hero-ramp) * 2),
    rgba(0, 0, 0, .12) calc(var(--hero-end) + var(--hero-ramp) * 2) calc(var(--hero-end) + var(--hero-ramp) * 3),
    transparent calc(var(--hero-end) + var(--hero-ramp) * 3)
  );
  mask-image: linear-gradient(
    90deg,
    #000 0 var(--hero-end),
    rgba(0, 0, 0, .58) var(--hero-end) calc(var(--hero-end) + var(--hero-ramp) * 1),
    rgba(0, 0, 0, .30) calc(var(--hero-end) + var(--hero-ramp) * 1) calc(var(--hero-end) + var(--hero-ramp) * 2),
    rgba(0, 0, 0, .12) calc(var(--hero-end) + var(--hero-ramp) * 2) calc(var(--hero-end) + var(--hero-ramp) * 3),
    transparent calc(var(--hero-end) + var(--hero-ramp) * 3)
  );
}
.hero::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 4;
  height: var(--u);
  background: repeating-linear-gradient(
    90deg,
    var(--ember) 0 var(--u2),
    #7A3F18 var(--u2) 16px
  );
}
/* width, not max-width. A max-width smaller than the left padding is a
   contradiction the browser resolves by collapsing the text column to
   nothing, which is exactly what used to happen past about 1500px: the
   gutter grew to 684px, the 60ch cap stayed at 590, and the hero became a
   2277px column of one-word lines. */
.hero__copy {
  position: relative;
  z-index: 3;
  box-sizing: border-box;
  width: var(--hero-end);
  max-width: 100%;
  padding: var(--s8) var(--s7) var(--s8) var(--edge);
}
.hero .eyebrow { color: var(--ember); }
.hero h1 {
  font-size: var(--t-2xl);
  line-height: 1.5;
  margin-bottom: var(--s5);
  color: #F2F6F5;
  text-wrap: balance;
  /* a one pixel shadow, the way a sprite title is given weight */
  text-shadow: 2px 2px 0 #0B0F0B;
}
.lede {
  font-size: var(--t-md);
  color: #C3D4D3;
  max-width: 52ch;
  margin-bottom: var(--s6);
}
/* one hard pixel of shadow under everything sitting on the scene — enough
   to hold an edge against the water, no blur involved */
.hero .eyebrow,
.hero .lede,
.hero .ticks li { text-shadow: var(--bw) var(--bw) 0 rgba(6, 10, 7, .9); }
.ticks { display: grid; gap: var(--s3); margin-bottom: var(--s6); }
.ticks li {
  position: relative; padding-left: 32px;
  font: 400 var(--t-xs)/1.55 var(--sans);
  color: var(--ice);
}
/* the checkmark is six pixels, placed by box-shadow. No border rotation
   trick, because a rotated square is not a pixel any more. */
.ticks li::before {
  content: "";
  position: absolute; left: 0; top: 9px;
  width: var(--u); height: var(--u);
  background: var(--ember);
  box-shadow:
    var(--u) var(--u) 0 var(--ember),
    var(--u2) var(--u) 0 var(--ember),
    12px 0 0 var(--ember),
    16px -4px 0 var(--ember),
    20px -8px 0 var(--ember);
}
.hero__cta { display: flex; flex-wrap: wrap; gap: var(--s4); }
.hero__cta .btn--solid {
  background: var(--ember); border-color: var(--night); color: var(--night);
  box-shadow: var(--u) var(--u) 0 #7A3F18;
}
.hero__cta .btn--solid:hover { background: #E4913F; box-shadow: 2px 2px 0 #7A3F18; }
.hero__cta .btn--solid:active { box-shadow: 0 0 0 #7A3F18; }
.hero__cta .btn:not(.btn--solid) {
  background: transparent; border-color: var(--ice); color: var(--ice);
  box-shadow: var(--u) var(--u) 0 rgba(224, 229, 220, .28);
}
.hero__cta .btn:not(.btn--solid):hover {
  background: var(--ice); color: var(--superior);
  box-shadow: 2px 2px 0 rgba(224, 229, 220, .28);
}

.hero__art {
  position: absolute;
  inset: 0;
  z-index: 0;
  margin: 0;
  overflow: hidden;
}
.hero__art svg { width: 100%; height: 100%; display: block; }
/* CRT scanlines: one dark row every four pixels, sitting on the scene and
   under the copy, so the picture reads as a screen and the text stays clean */
.hero__art::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    180deg,
    rgba(6, 10, 7, .30) 0 var(--bw),
    transparent var(--bw) var(--u)
  );
}

/* --- the only two animations on the site ------------------------------
   Both are stepped. A pixel scene has no tween frames: a star is on or it
   is off, and the light on the water moves a whole pixel or none at all. */
@keyframes blink { 0%, 62% { opacity: 1; } 63%, 100% { opacity: .15; } }
@keyframes drift { from { transform: translateX(0); } to { transform: translateX(3px); } }

.hero__art .stars rect {
  animation: blink 4.5s steps(1, end) infinite;
}
.hero__art .stars rect:nth-child(3n)   { animation-duration: 6.5s; animation-delay: -1.2s; }
.hero__art .stars rect:nth-child(4n)   { animation-duration: 5.5s; animation-delay: -3.4s; }
.hero__art .stars rect:nth-child(5n+2) { animation-duration: 7.5s; animation-delay: -2.1s; }
.hero__art .road rect {
  animation: drift 3.2s steps(3, end) infinite alternate;
}
.hero__art .road rect:nth-child(even) { animation-duration: 4.4s; animation-delay: -1.6s; }
.hero__art .road rect:nth-child(3n)   { animation-duration: 5.6s; animation-delay: -2.8s; }

@media (prefers-reduced-motion: reduce) {
  .hero__art .stars rect,
  .hero__art .road rect { animation: none; }
}

/* No mask override is needed between 760 and 1000 any more: --hero-end is
   already relative to the copy column, so the ramp follows it down. All
   this band has to do is let the copy use the full measure. */
@media (max-width: 1000px) {
  .hero { --hero-ramp: clamp(40px, 6%, 96px); }
  .hero__copy { padding-right: var(--s5); }
}

/* A short window — a laptop at 1366x768, a phone turned sideways — must not
   be handed a hero taller than the screen it is on. Trim the vertical
   padding rather than the copy. */
@media (max-height: 760px) and (min-width: 761px) {
  .hero { min-height: 0; }
  .hero__copy { padding-top: var(--s6); padding-bottom: var(--s6); }
  .hero h1 { margin-bottom: var(--s4); }
  .lede { margin-bottom: var(--s4); }
  .ticks { gap: var(--s2); margin-bottom: var(--s4); }
}

/* Portrait: a 16:9 scene cropped to a phone is a black slab, so the whole
   picture parks along the bottom at full width instead and the copy sits on
   flat night above it — no scrim needed, and the sun stays in frame.

   The reserved space below the copy is aspect-ratio arithmetic, not a magic
   number: the art is 16:9 across the full content box, so it is exactly
   9/16 of that box tall. 56vw was close, and wrong by the scrollbar. */
@media (max-width: 760px) {
  .hero {
    display: block;
    min-height: 0;
    background-image:
      linear-gradient(rgba(213, 228, 227, .05) var(--bw), transparent var(--bw)),
      linear-gradient(90deg, rgba(213, 228, 227, .05) var(--bw), transparent var(--bw)),
      repeating-conic-gradient(rgba(79, 117, 101, .16) 0% 25%, transparent 0% 50%);
    background-size: 32px 32px, 32px 32px, var(--u) var(--u);
  }
  .hero::before { display: none; }
  .hero__art { inset: auto 0 var(--u) 0; }
  .hero__art svg { height: auto; aspect-ratio: 16 / 9; }
  .hero__copy {
    width: 100%;
    padding: var(--s7) var(--gut) calc(56.25% + var(--s5));
  }
}

@media (max-width: 560px) {
  .hero__copy { padding-bottom: calc(56.25% + var(--s4)); }
  .lede { margin-bottom: var(--s5); }
  .ticks { gap: var(--s3); margin-bottom: var(--s5); }
  .hero__cta { display: grid; grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------- strip */
.strip {
  position: relative;
  z-index: 4;
  --notch: var(--stone-100);
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: var(--bw);
  background: var(--stone-900);
  border: var(--bw) solid var(--stone-900);
  border-top: var(--u) solid var(--ember);
  /* the same --edge every other section uses, so the left rule of the page
     is one line from the header down */
  margin: -28px var(--edge) 0;
  box-shadow: var(--u) var(--u) 0 rgba(23, 32, 37, .28);
}
.strip__item {
  background: var(--paper);
  padding: var(--s5);
  display: flex; flex-direction: column; gap: var(--s2);
}
.strip__item + .strip__item { padding-left: var(--s5); }
.strip__k { font: 700 var(--t-xl)/1.1 var(--disp); }
.strip__item:nth-child(odd) .strip__k { color: var(--rust); }
.strip__item:nth-child(even) .strip__k { color: var(--harbour); }
.strip__v { font-size: var(--t-2xs); color: var(--stone-600); }
@media (max-width: 860px) { .strip { grid-template-columns: repeat(2, 1fr); } }
/* Below 760 the sunrise is parked along the bottom of the hero, so a strip
   pulled up 28px lands on top of it. Sit it below the picture instead. */
@media (max-width: 760px) {
  .strip { margin-top: var(--s5); }
}
@media (max-width: 480px) {
  .strip { grid-template-columns: 1fr; }
  .strip__item { padding: var(--s4) !important; }
}

/* ----------------------------------------------------------------- menu */
.menu {
  position: relative;
  isolation: isolate;
  max-width: none;
  margin: 0;
  padding: var(--s8) var(--edge) var(--s8);
  background:
    linear-gradient(rgba(46, 101, 112, .05) var(--bw), transparent var(--bw)),
    linear-gradient(90deg, rgba(46, 101, 112, .05) var(--bw), transparent var(--bw)),
    repeating-conic-gradient(var(--dither-ink) 0% 25%, transparent 0% 50%),
    var(--stone-100);
  background-size: 32px 32px, 32px 32px, var(--u) var(--u), auto;
  overflow: hidden;
}
.menu::before {
  content: "TTG / PRICE LIST";
  position: absolute;
  top: var(--s7);
  right: var(--edge);
  z-index: -1;
  font: 700 clamp(24px, 4.4vw, 56px)/1 var(--disp);
  letter-spacing: 0;
  color: rgba(23, 32, 37, .05);
  white-space: nowrap;
}
/* the watermark is decoration; on a phone it is decoration nobody has the
   width for, and it collides with the section heading */
@media (max-width: 760px) { .menu::before { display: none; } }

/* .menu is clipped only to keep that watermark inside the section. The clip
   costs more than it is worth on a phone: an ancestor with overflow:hidden
   becomes the scrollport for any sticky descendant, which meant the sticky
   filter bar below silently never stuck to anything. With the watermark
   already gone at this width there is nothing left to clip. */
@media (max-width: 760px) { .menu { overflow: visible; } }

.sec__head { max-width: 62ch; margin-bottom: var(--s6); }
.sec__head h2 { font-size: var(--t-2xl); margin-bottom: var(--s4); }
.sec__sub { color: var(--stone-600); font-size: var(--t-md); }
.sec__sub strong { color: var(--stone-900); }

.filterbar {
  --notch: var(--stone-100);
  position: relative;
  padding: var(--s4);
  border: var(--bw) solid var(--stone-900);
  border-left: var(--u) solid var(--harbour);
  margin-bottom: var(--s7);
  background: var(--paper);
  box-shadow: var(--drop);
}
.service-search {
  display: grid;
  grid-template-columns: 132px minmax(240px, 420px);
  align-items: center;
  gap: var(--s3);
  max-width: 552px;
  margin-bottom: var(--s4);
  color: var(--stone-600);
  font: 400 var(--t-md)/1.3 var(--mono);
}
.service-search input {
  width: 100%;
  min-height: 48px;
  padding: 10px 12px;
  border: var(--bw) solid var(--stone-900);
  border-radius: 0;
  background: var(--stone-050);
  color: var(--stone-900);
  /* 16px floor on purpose: iOS Safari zooms the whole page in on any input
     it decides is smaller than that, and the zoom does not come back out */
  font: 400 max(16px, var(--t-2xs))/1.2 var(--sans);
  /* inset hard shadow: a sunken field, drawn the way a sprite would be */
  box-shadow: inset 2px 2px 0 rgba(23, 32, 37, .16);
}
.service-search input::placeholder { color: var(--stone-500); opacity: 1; }
.service-search input::-webkit-search-cancel-button { cursor: pointer; }
.filters {
  display: flex; flex-wrap: wrap; gap: var(--s3);
}
.filter-select { display: none; }
.chip {
  min-height: 44px;
  padding: 9px 14px;
  border: var(--bw) solid var(--stone-900);
  border-radius: 0;
  background: var(--stone-050);
  font: 400 var(--t-md)/1 var(--mono);
  letter-spacing: .02em;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 2px 2px 0 var(--stone-900);
  transition:
    transform .08s steps(2, end),
    box-shadow .08s steps(2, end),
    background-color .08s steps(2, end),
    color .08s steps(2, end);
}
.chip { display: inline-flex; align-items: center; gap: var(--s2); }
/* the swatch teaches the colour code before anyone clicks anything —
   and at this resolution it is exactly one pixel */
.chip[data-tone]::before {
  content: ""; width: var(--u2); height: var(--u2);
  background: var(--tone); border-radius: 0;
}
.chip:hover { color: var(--tone); transform: translate(1px, 1px); box-shadow: 1px 1px 0 var(--stone-900); }
.chip.is-on {
  background: var(--tone); color: var(--paper);
  transform: translate(2px, 2px); box-shadow: 0 0 0 var(--stone-900);
}
.chip.is-on::before { background: var(--paper); }
.chip[data-filter="all"] { --tone: var(--stone-900); }
.filters__status {
  margin-top: var(--s4);
  font: 400 var(--t-xs)/1.5 var(--mono);
  color: var(--stone-600);
}
.filters__empty { color: var(--stone-600); font-size: var(--t-xs); padding: var(--s6) 0; }

/* ---- the filter bar on a phone ---------------------------------------
   The old mobile version swapped the chips for a <select>. That cost two
   taps instead of one and, worse, threw away the colour swatches — and
   the colour code is the whole navigation shortcut on a list of 22.

   The chips stay. They become one row that scrolls sideways, snapping to
   each chip, with the row itself pinned under the header so you can
   re-filter from anywhere in the list without scrolling back up. The
   <select> stays in the DOM as the script's state, just not on screen.
   -------------------------------------------------------------------- */
@media (max-width: 720px) {
  /* The panel box dissolves, so its four children become direct children of
     .menu. That is what lets the chip row alone be the sticky element
     rather than the whole panel: pinning the search field and the status
     line along with it held 28% of a phone screen permanently, and neither
     of them is something you reach for twice. The chips are. */
  .filterbar { display: contents; }
  .filterbar::after { display: none; }
  .filter-select { display: none; }

  .service-search {
    display: block;
    max-width: none;
    margin: 0 0 var(--s3);
  }
  /* the visible label goes; the placeholder says the same thing, and the
     label is still there to be read aloud */
  .service-search > span {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .filters {
    position: sticky;
    top: var(--bar-h);
    z-index: 30;
    display: flex;
    flex-wrap: nowrap;
    gap: var(--s2);
    /* full bleed, so the row can scroll past the section gutter */
    margin: 0 calc(var(--edge) * -1) var(--s5);
    padding: var(--s2) var(--edge) 10px;
    background: var(--paper);
    border-bottom: var(--bw) solid var(--stone-900);
    box-shadow: 0 var(--u) 0 rgba(23, 32, 37, .12);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .filters::-webkit-scrollbar { display: none; }
  .chip { flex: none; scroll-snap-align: start; }

  .filters__status {
    margin: 0 0 var(--s5);
    font-size: var(--t-2xs);
  }
}

.group { margin-bottom: var(--s8); }
.group[hidden] { display: none; }
.group__h {
  display: flex; align-items: center; gap: var(--s3);
  font: 400 var(--t-lg)/1.2 var(--mono);
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--tone);
  padding-bottom: var(--s4);
  margin-bottom: 0;
}
/* the rule carries the group's colour out across the page as a dashed pixel
   run — 4px on, 4px off — so the eye can find "the green section" without
   reading a single word */
.group__h::after {
  content: ""; flex: 1; height: var(--u);
  background: repeating-linear-gradient(
    90deg,
    var(--tone) 0 var(--u),
    transparent var(--u) var(--u2)
  );
}

/* the board: sprite cards on a hairline-free grid. Every card is a tile:
   2px outline, 4px drop, and it lifts by displacement on hover. */
/* Stated column counts rather than auto-fill: with 22 cards on the board,
   auto-fill lands within a pixel or two of flipping between three and four
   columns at common laptop widths, so whether a scrollbar is showing
   changes the layout. These four steps do not. */
.board {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s5);
}
@media (max-width: 560px)  { .board { grid-template-columns: 1fr; } }
@media (min-width: 901px)  { .board { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
/* a 27" monitor has room for a fourth without the cards going soft */
@media (min-width: 1800px) { .board { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.svc {
  position: relative;
  --notch: var(--stone-100);
  display: flex; flex-direction: column;
  background: var(--paper);
  border: var(--bw) solid var(--stone-900);
  border-radius: 0;
  box-shadow: var(--drop);
  transition:
    transform .08s steps(2, end),
    box-shadow .08s steps(2, end),
    border-color .08s steps(2, end);
}
.svc[hidden] { display: none; }
.svc:hover {
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 var(--tone);
}

.svc__fig {
  position: relative;
  isolation: isolate;
  margin: 0;
  aspect-ratio: 16 / 9;
  background: var(--night);
  border-bottom: var(--bw) solid var(--stone-900);
  display: grid; place-items: center;
  overflow: hidden;
}
.svc__fig img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  image-rendering: crisp-edges;
  image-rendering: pixelated;
}
/* scanline: one transparent pixel row every four, sitting over the sprite.
   Faint enough to read as CRT texture, not as damage. */
.svc__fig::after {
  content: "";
  position: absolute; inset: 0; z-index: 2;
  pointer-events: none;
  background: repeating-linear-gradient(
    180deg,
    rgba(11, 15, 11, .16) 0 var(--bw),
    transparent var(--bw) var(--u)
  );
}

.svc__body { padding: var(--s5) var(--s5) var(--s4); flex: 1; }
/* card titles are the scanning layer of a 22-item list, so they get the
   readable face rather than the loud one */
.svc__body h4 {
  font-family: var(--mono);
  font-weight: 400;
  font-size: var(--t-lg);
  line-height: 1.3;
  margin-bottom: var(--s3);
  text-wrap: balance;
}
.svc__body p { font-size: var(--t-2xs); color: var(--stone-600); }
.svc__meta {
  margin-top: var(--s4) !important;
  font: 400 var(--t-xs)/1.4 var(--mono) !important;
  letter-spacing: .02em;
  /* stone-500 is 4.48:1 on paper — just under the 4.5 it needs */
  color: var(--stone-600) !important;
}

/* the price sits behind a dashed pixel rule, the perforation on a ticket */
.svc__price {
  padding: var(--s4) var(--s5) var(--s5);
  border-top: var(--bw) solid transparent;
  border-image: repeating-linear-gradient(
    90deg,
    var(--stone-300) 0 var(--u),
    transparent var(--u) var(--u2)
  ) 2;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2);
}
.p {
  font: 700 var(--t-num)/1 var(--num);
  letter-spacing: 0;
  color: var(--stone-900);
}
.p--free { color: var(--rust); }
.p__to { font-size: .78em; }
.p__unit { font: 400 var(--t-xs)/1 var(--mono); color: var(--stone-600); }
.p__compare {
  margin-left: var(--u);
  font: 400 var(--t-xs)/1 var(--mono);
  color: var(--stone-600);
  /* a one pixel rule, not two: at this size a 2px strike eats the digits */
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}
.p__note {
  flex-basis: 100%;
  font: 400 var(--t-3xs)/1.45 var(--sans);
  color: var(--stone-600);
  margin-top: var(--u);
}

/* ---- the card on a phone ---------------------------------------------
   One full-bleed 16:9 illustration per card, 22 cards deep, made the price
   list twenty thousand pixels tall on a 375px screen. Nobody scrolls a
   price list twenty-five screens long looking for a battery.

   So below 560 the illustration stops being the card and becomes its
   marker: a framed 96x54 tile — which is the PNG's own native size, so
   the sprite is finally mapped one source pixel to one CSS pixel instead
   of being blown up by a fractional 3.49x — floated beside the title,
   with the copy running on past it. Same content, same art, a little
   under half the height.
   -------------------------------------------------------------------- */
@media (max-width: 560px) {
  .svc { display: block; }
  .svc__fig {
    float: left;
    width: 96px; height: 54px;
    aspect-ratio: auto;
    margin: var(--s4) var(--s3) var(--s2) var(--s4);
    border: var(--bw) solid var(--stone-900);
    box-shadow: var(--bw) var(--bw) 0 rgba(23, 32, 37, .22);
  }
  .svc__body { padding: var(--s4) var(--s4) var(--s3); }
  .svc__body h4 { text-wrap: pretty; }
  .svc__price { clear: both; padding: var(--s3) var(--s4) var(--s4); }
}

.menu__foot {
  border-top: var(--bw) solid transparent;
  border-image: repeating-linear-gradient(
    90deg,
    var(--stone-300) 0 var(--u),
    transparent var(--u) var(--u2)
  ) 2;
  padding-top: var(--s5);
  max-width: 58ch;
  color: var(--stone-600);
  font-size: var(--t-xs);
}

/* ------------------------------------------------------------------ how */
.how {
  position: relative;
  max-width: none;
  margin: 0;
  padding: var(--s8) var(--edge);
  border-top: var(--u) solid var(--night);
  background:
    linear-gradient(rgba(213, 228, 227, .05) var(--bw), transparent var(--bw)),
    linear-gradient(90deg, rgba(213, 228, 227, .05) var(--bw), transparent var(--bw)),
    repeating-conic-gradient(rgba(57, 116, 104, .16) 0% 25%, transparent 0% 50%),
    var(--superior);
  background-size: 32px 32px, 32px 32px, var(--u) var(--u), auto;
  color: var(--ice);
}
.how h2 { font-size: var(--t-xl); margin-bottom: var(--s6); }
.steps {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 0;
  border: var(--bw) solid var(--night);
  border-top: var(--u) solid var(--ember);
  background: rgba(8, 23, 29, .4);
  box-shadow: var(--u) var(--u) 0 rgba(8, 14, 10, .45);
}
.steps li {
  padding: var(--s5);
  border-right: var(--bw) solid var(--night);
}
.steps li:last-child { border-right: 0; }
.steps li + li { padding-left: var(--s5); }
.steps__n {
  display: block;
  font: 700 var(--t-lg)/1 var(--num);
  margin-bottom: var(--s4);
}
.steps li .steps__n { color: #F0A064; }
.steps h3 { font-family: var(--mono); font-weight: 400; font-size: var(--t-lg); line-height: 1.3; margin-bottom: var(--s3); }
.steps p { font-size: var(--t-2xs); color: #B7CBCB; }
@media (max-width: 820px) {
  .steps { grid-template-columns: 1fr 1fr; }
  .steps li:nth-child(2) { border-right: 0; }
  .steps li:nth-child(3) { padding-left: var(--s5); border-top: var(--bw) solid var(--night); }
  .steps li:nth-child(4) { border-top: var(--bw) solid var(--night); }
}
@media (max-width: 520px) {
  .steps { grid-template-columns: 1fr; }
  .steps li { border-right: 0; padding-left: var(--s5) !important; }
  .steps li + li { border-top: var(--bw) solid var(--night); }
}

/* -------------------------------------------------------------- compare */
.compare {
  max-width: none; margin: 0;
  padding: var(--s8) var(--edge);
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
  gap: var(--s8);
  border-top: var(--u) solid var(--night);
  background:
    repeating-conic-gradient(rgba(23, 32, 37, .06) 0% 25%, transparent 0% 50%)
      0 0 / var(--u) var(--u),
    var(--paper-deep);
}
.compare h2 { font-size: var(--t-xl); margin-bottom: var(--s5); }
.compare__copy p { color: var(--stone-600); max-width: 54ch; margin-bottom: var(--s4); font-size: var(--t-xs); }
.compare__caveat {
  border-left: var(--u) solid var(--amethyst);
  padding-left: var(--s4);
  font-size: var(--t-2xs) !important;
}
/* small dark vignette, sitting in the space the prose leaves behind */
.vignette { margin: var(--s7) 0 0; max-width: 460px; }
.vignette svg {
  width: 100%; height: auto;
  border: var(--bw) solid var(--stone-900);
  box-shadow: var(--u2) var(--u2) 0 rgba(23, 32, 37, .18);
}
.vignette figcaption {
  margin-top: var(--s4);
  font: 400 var(--t-3xs)/1.6 var(--sans);
  color: var(--stone-600);
  max-width: 44ch;
}

.compare__table {
  --notch: var(--paper-deep);
  position: relative;
  align-self: start;
  padding: var(--s5);
  border: var(--bw) solid var(--stone-900);
  border-top: var(--u) solid var(--harbour);
  background: var(--paper);
  box-shadow: 6px 6px 0 rgba(23, 32, 37, .22);
}
/* the two number columns are sized in ch off their own face, so they hold
   "$99–129" without a fixed px width that a phone cannot afford */
.ct__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: var(--s4);
  align-items: baseline;
  padding: var(--s3) 0;
  border-bottom: var(--bw) solid transparent;
  border-image: repeating-linear-gradient(
    90deg,
    var(--stone-300) 0 var(--u),
    transparent var(--u) var(--u2)
  ) 2;
  font-size: var(--t-2xs);
}
.ct__row--head {
  border-image: none;
  border-bottom: var(--u) solid var(--stone-900);
  font: 400 var(--t-2xs)/1.2 var(--mono);
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--stone-600);
  padding-bottom: var(--s3);
}
.ct__row--head span:nth-child(2),
.ct__row--head span:nth-child(3) { text-align: right; min-width: 7ch; }
.ct__was {
  font: 400 var(--t-xs)/1 var(--mono);
  color: var(--stone-600);
  text-align: right; min-width: 7ch;
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}
.ct__now {
  font: 400 var(--t-xs)/1 var(--mono);
  color: #3D6355;
  text-align: right; min-width: 7ch;
}
.ct__src { margin-top: var(--s5); font-size: var(--t-3xs); color: var(--stone-600); max-width: 44ch; }
/* minmax(0,…) rather than 1fr: the table's min-content is wide enough to
   push the column past the viewport on a narrow phone otherwise */
@media (max-width: 900px) { .compare { grid-template-columns: minmax(0, 1fr); gap: var(--s6); } }
@media (max-width: 480px) {
  .compare__table { padding: var(--s4); }
  .ct__row { gap: var(--s2); }
  .vignette { margin-top: var(--s6); }
}

/* ----------------------------------------------------------------- area */
.area {
  --notch: var(--stone-100);
  position: relative;
  display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: var(--bw);
  background: var(--stone-900);
  border: var(--bw) solid var(--stone-900);
  max-width: none;
  /* the gutter is applied as margin so the ruled box sits inside the page rhythm */
  margin: var(--s8) var(--edge);
  box-shadow: 6px 6px 0 rgba(23, 32, 37, .22);
}
.area__box { background: var(--paper); padding: var(--s7) var(--s6); }
.area__box--hours { background: var(--superior); color: var(--ice); }
.area h2 { font-size: var(--t-xl); margin-bottom: var(--s4); }
.area__lead { color: var(--stone-600); max-width: 46ch; margin-bottom: var(--s5); font-size: var(--t-xs); }
.area__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 150px), 1fr));
  gap: 0;
  border-top: var(--bw) solid var(--stone-200);
}
.area__list li {
  padding: var(--s3) 0;
  border-bottom: var(--bw) solid var(--stone-200);
  font: 400 var(--t-xs)/1.4 var(--mono);
  color: var(--stone-800);
}
.hours { border-top: var(--bw) solid rgba(198, 216, 218, .25); margin-bottom: var(--s5); }
.hours div {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--s4);
  padding: var(--s3) 0; border-bottom: var(--bw) solid rgba(198, 216, 218, .25);
}
.hours dt { font-size: var(--t-2xs); }
.hours dd { margin: 0; font: 400 var(--t-xs)/1 var(--mono); color: #EDC28C; }
.area__note { font-size: var(--t-2xs); color: #A4BEC1; max-width: 40ch; }
@media (max-width: 860px) {
  .area { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .area__box { padding: var(--s6) var(--s5); }
}

/* ------------------------------------------------------------------ faq */
.faq {
  max-width: none; margin: 0;
  padding: var(--s8) var(--edge);
  display: grid; grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: var(--s7);
  border-top: var(--bw) solid var(--stone-200);
}
.faq h2 { font-size: var(--t-xl); }
.faq__list { border-top: var(--u) solid var(--stone-900); }
.faq details { border-bottom: var(--bw) solid var(--stone-200); }
.faq summary {
  list-style: none; cursor: pointer;
  padding: var(--s4) var(--s7) var(--s4) 0;
  position: relative;
  min-height: 44px;
  display: flex; align-items: center;
  font: 500 var(--t-xs)/1.5 var(--sans);
  transition: color .08s steps(2, end);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--harbour); }
/* a pixel plus, drawn as two bars — closed shows both, open drops the
   vertical one and leaves a minus. No rotation: pixels do not rotate. */
.faq summary::before,
.faq summary::after {
  content: "";
  position: absolute; right: var(--s3); top: 50%;
  background: var(--stone-400);
  transition: background-color .08s steps(2, end), opacity .08s steps(2, end);
}
.faq summary::before { width: var(--u); height: 20px; margin-top: -10px; margin-right: var(--u2); }
.faq summary::after  { width: 20px; height: var(--u); margin-top: -2px; }
.faq details[open] summary::before { opacity: 0; }
.faq details[open] summary::after { background: var(--harbour); }
.faq details p { padding: 0 var(--s7) var(--s5) 0; color: var(--stone-600); max-width: 62ch; font-size: var(--t-xs); }
@media (max-width: 800px) { .faq { grid-template-columns: 1fr; gap: var(--s5); } }
@media (max-width: 480px) {
  .faq summary { padding-right: var(--s6); }
  .faq details p { padding-right: 0; }
}

/* -------------------------------------------------------------- contact */
.contact {
  background:
    repeating-conic-gradient(rgba(79, 117, 101, .2) 0% 25%, transparent 0% 50%)
      0 0 / var(--u) var(--u),
    var(--night);
  color: var(--ice);
  border-top: var(--u) solid var(--ember);
}
.contact__inner {
  max-width: none; margin: 0;
  padding: var(--s8) var(--edge);
}
.contact .eyebrow--light { color: var(--ember); }
.contact h2 {
  font-size: var(--t-2xl);
  line-height: 1.4;
  margin-bottom: var(--s5);
  color: #F2F6F5;
  text-shadow: var(--u) var(--u) 0 #0B0F0B;
}
.contact__lede { color: #ADC4C7; max-width: 50ch; margin-bottom: var(--s6); font-size: var(--t-md); }
.contact__acts { display: flex; flex-wrap: wrap; gap: var(--s4); }
/* the three ways to reach someone are the point of the page — on a phone
   they get the full width each rather than two-and-a-half per row */
@media (max-width: 560px) {
  .contact__acts { display: grid; grid-template-columns: 1fr; gap: var(--s3); }
}
.contact .btn--light {
  background: var(--ember); border-color: var(--night); color: var(--night);
  box-shadow: var(--u) var(--u) 0 #7A3F18;
}
.contact .btn--light:hover { background: #E4913F; color: var(--night); box-shadow: 2px 2px 0 #7A3F18; }
.contact .btn--light:active { box-shadow: 0 0 0 #7A3F18; }

/* the aurora runs edge to edge and hands off into the footer */
.aurora { line-height: 0; background: #111510; }
.aurora svg { width: 100%; height: clamp(150px, 20vw, 280px); display: block; }

/* ----------------------------------------------------------------- foot */
.foot {
  background: #0C0F0D;
  color: var(--ice-dim);
  padding: var(--s6) var(--edge) var(--s8);
  border-top: var(--bw) solid transparent;
  border-image: repeating-linear-gradient(
    90deg,
    rgba(224, 229, 220, .2) 0 var(--u),
    transparent var(--u) var(--u2)
  ) 2;
}
.foot p { margin: 0; font-size: var(--t-2xs); }
.foot strong { color: var(--ice); font-family: var(--mono); font-weight: 400; font-size: var(--t-xs); }
.foot__meta { margin-top: var(--s4) !important; font-size: var(--t-3xs); color: #86999E; }

/* -------------------------------------------------------- print the menu */
@media print {
  .bar, .hero__art, .contact__acts, .filters { display: none; }
  body { background: #fff; }
  .board { break-inside: avoid; }
  .svc { box-shadow: none; }
  .svc__fig { display: none; }
  .svc::after, .strip::after, .filterbar::after,
  .area::after, .compare__table::after { display: none; }
}
