/* koda-chrome.css — the bar and the footer, on every pre-login page
 * ===========================================================================
 * Jeremy, 2026-09-14: *"The pre-login pages per-service (and likely per area,
 * etc. Any pre-login page) should all have the bar the same up top. Please fix
 * that. Same with the whole footer section."*
 *
 * ═══ WHAT WAS WRONG ═══
 *
 * There were two chromes. The home page had this one — navy rail, struck-plate
 * mark, gold review pennant, the call lockup, a sign-in drawer — and the other
 * twenty pre-login pages had a `.nav` out of styles.css: a different logo at a
 * different size, a different link set, a burgundy "Get a Quote" pill, no
 * pennant and no drawer. The footers were worse: THREE different ones across
 * those twenty pages (`.footer`, a `section-burgundy` with sixty inline
 * styles, and a bare <footer>), each with its own link list.
 *
 * ═══ WHAT THIS IS ═══
 *
 * The surviving chrome, MOVED out of home.css rather than copied out of it, so
 * there is one place to change the bar and one place to change the footer.
 * koda-chrome.js is the behaviour half.
 *
 * It holds, in order:
 *   1. the two TOKEN blocks — :root primitives, then the .koda-v2 aliases
 *      onto Nocturne (koda-theme.css must be linked BEFORE this file, because
 *      the aliases resolve to its --koda-* values)
 *   2. a short BASE block: only what the chrome itself needs, deliberately
 *      never a page reset (see the note on it below)
 *   3. the BAR, the review pennant, the call lockup, the mobile sheet
 *   4. the SIGN-IN DRAWER and the fields and buttons inside it
 *   5. the FOOTER
 *
 * ═══ THE SCOPE IS `body.koda-chrome`, AND THAT IS THE WHOLE SAFETY MODEL ═══
 *
 * Every rule is scoped to an element of the chrome — `.bar`, `.seal`,
 * `.drawer`, `.foot` — under a `body.koda-chrome` prefix. NOTHING in here
 * styles a bare `a`, `h2`, `p` or `img`, because this file now loads on twenty
 * pages whose own content is styled by styles.css and would be trampled by a
 * generic selector. home.css may do that; this file may not. If you add a rule
 * here, it must name a chrome class.
 *
 * On index.html <body> carries `koda-v2 koda-chrome koda-page-home` and this
 * file is linked BEFORE home.css, so the home page can still override anything
 * here at equal specificity.
 * =========================================================================== */

/* ── Tokens ─────────────────────────────────────────────────────────────────
 *
 * TWO BLOCKS, AND THE SPLIT MATTERS.
 *
 * Nocturne declares its palette on `.koda-v2` (the class on <body>), not on
 * :root. A `var(--koda-night)` referenced FROM :root therefore resolves to
 * nothing — :root is the ancestor, and custom properties only inherit
 * downwards. So every colour alias lives on `.koda-v2` below, where the theme's
 * variables are actually in scope, and only the palette-free tokens sit on
 * :root. home.js reads --bar-h off documentElement, which is why that one in
 * particular has to stay there.
 * ------------------------------------------------------------------------- */
:root{
  --font-display: 'Nanum Myeongjo', Georgia, 'Times New Roman', serif;
  --font-body: 'DM Sans', system-ui, -apple-system, sans-serif;

  --bar-h: 76px;
  /* Nocturne runs a 4px card / 3px pill radius — a squarer, more editorial
     corner than a rounded UI kit. Adopted, so the booking card and a service
     card on /carpet are recognisably the same object. */
  --radius: 4px;
  --radius-sm: 3px;
  --ease: cubic-bezier(.22, .61, .36, 1);

  /* The press. Navy-inked, so nothing on the page casts a warm shadow. */
  --lift-1: 0 1px 2px rgba(16,24,36,.05), 0 2px 6px rgba(16,24,36,.05);
  --lift-2: 0 1px 2px rgba(16,24,36,.06), 0 8px 20px -6px rgba(16,24,36,.14),
            inset 0 1px 0 rgba(255,255,255,.9);
  --lift-3: 0 2px 4px rgba(16,24,36,.07), 0 20px 44px -14px rgba(16,24,36,.22),
            inset 0 1px 0 rgba(255,255,255,.9);
  --lift-4: 0 3px 6px rgba(16,24,36,.08), 0 36px 70px -22px rgba(16,24,36,.32),
            inset 0 1px 0 rgba(255,255,255,.94);
  --press:  inset 0 2px 5px rgba(16,24,36,.14), inset 0 -1px 0 rgba(255,255,255,.5);

  /* PAPER GRAIN. Two turbulence octaves, painted only ever through a
     low-opacity pseudo-element (see the note by .book). Inline, so it costs no
     request and cannot 404 into a grey page. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");

  /* WOVEN FIBRE. A carpet loop abstracted to two crossing hairlines — the one
     motif on the page that is about the product itself. Navy, at 5%. */
  /* The closing band's lattice: --weave's two strokes at twice the scale, in
     gilt rather than navy, for a DARK ground. See .close-band. */
  --weave-gold: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='68' height='68'%3E%3Cg fill='none' stroke='%23c9a44c' stroke-opacity='.11' stroke-width='1.4'%3E%3Cpath d='M0 34c17 0 17-22 34-22s17 22 34 22'/%3E%3Cpath d='M34 0c0 17-22 17-22 34s22 17 22 34'/%3E%3C/g%3E%3C/svg%3E");
  --weave: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='34' height='34'%3E%3Cg fill='none' stroke='%2316202e' stroke-opacity='.05' stroke-width='1'%3E%3Cpath d='M0 17c8.5 0 8.5-11 17-11s8.5 11 17 11'/%3E%3Cpath d='M17 0c0 8.5-11 8.5-11 17s11 8.5 11 17'/%3E%3C/g%3E%3C/svg%3E");
}

/* Every colour on this page is an ALIAS onto Nocturne. No hex belongs here. */
.koda-v2{
  /* Navy: the ink, the chrome, the anchor bands. */
  --ink:        var(--koda-night);      /* #16202e — nav, footer, dark bands */
  --ink-mid:    var(--koda-night-2);    /* #1d2b3d — anchor bands            */
  --ink-lift:   var(--koda-night-3);    /* #26374d — raised surfaces on navy */
  --ink-deep:   var(--koda-night);

  /* Steel: supporting accents and links. --steel-deep is the one that clears
     AA on mist, per Nocturne's own note; small type uses it, never --steel. */
  --steel:      var(--koda-slate);      /* #607898 */
  --steel-deep: var(--koda-slate-ink);  /* #566d8a */
  --steel-soft: var(--koda-mist);

  /* Ground: one white and one mist. The warm neutrals are retired. */
  --page:       var(--koda-white);
  --page-deep:  var(--koda-mist);       /* #eff3f7 — the ONE alternate band */
  --paper:      var(--koda-white);
  --text:       var(--koda-ink);        /* #1e2530 */
  --muted:      rgba(30, 37, 48, .68);
  /* SECONDARY COPY INSIDE A FORM IS NOT DECORATION. --muted (.68 → about #5f646c
     on white) is the right weight for a caption under a photograph and the wrong
     one for the line that tells somebody what a question is asking. Jeremy,
     2026-09-10: "darken fonts to ensure readability". Every hint, label and
     helper line inside the booking card uses this instead — .84 lands near
     #45494f, roughly 8:1 on white, and still reads as the quieter of two voices
     next to full ink. KODA's audience skews 35+; this is the same reasoning as
     the §4.1 size floors, applied to contrast. */
  --ink-soft:   rgba(30, 37, 48, .84);

  /* Burgundy: the ACTION colour. Buttons. That is the entire list. */
  --act:        var(--koda-burgundy);
  --act-hi:     var(--koda-burgundy-hi);

  /* One step down from the brand slate, and it exists for exactly one job:
     type set OVER THE PHOTOGRAPH. --steel-deep (#566d8a) is Nocturne's floor
     for small text on MIST — a flat, known surface. The hero is not one: it is
     a sunlit room under a thin veil, and the same slate that clears AA on mist
     lands around 3.9:1 on the brightest patches of it. Jeremy, 2026-09-10:
     "Darken all of the text so it stands out on the white background."
     #3d5474 is the brand slate driven down until it clears 7:1 on the lightest
     thing the veil can produce, which is what the emphasis in the headline and
     the labels under it are actually sitting on. It is a shade of the brand
     colour, derived the same way --gold-deep and --gold-ink are, and it is
     never used anywhere the plain slate already works. */
  --steel-ink:  #3d5474;

  /* Gilt: the accent of last resort — stars, the seal, one hairline, the top
     edge of the booking card. Never a large area; never small text on white,
     where it measures 2.37:1. */
  --gold:       var(--koda-gilt);
  --gold-lit:   #e2c67f;                /* one step up, for type on navy    */
  --gold-deep:  #8a6a24;                /* one step down, for edges on gold */
  --gold-ink:   #2c2109;                /* text ON gilt — 8.1:1             */

  /* Lines: Nocturne's, so a rule here matches a rule on /carpet. */
  --rule:       var(--koda-rule);       /* rgba(30,37,48,.14) */
  --rule-soft:  rgba(30, 37, 48, .08);
  --rule-firm:  rgba(30, 37, 48, .26);
  --rule-night: var(--koda-rule-night);
}

/* ═══ BASE — AND IT IS NOT A RESET ════════════════════════════════════
   home.css opens with `*{margin:0;padding:0;box-sizing:border-box}`, a `body`
   rule and a page-wide grain overlay. NONE of that came with the chrome, and
   the omission is deliberate: those three would restyle the body copy of
   twenty pages that never asked for it. styles.css already carries its own
   `*` reset on those pages.

   What IS here is the handful of things the chrome markup cannot paint
   without, each of them named down to a chrome class:

     .wrap    the bar and the footer both use it for the content column, and
              only inside those two — never as a page-wide utility.
     .skip    the skip link, which is chrome by definition.
     ul/li    the footer's link lists, in case a page's own reset is not the
              one home.css ships.
     h2/h3    the drawer's heading and the footer's column heads, given their
              display face explicitly rather than inheriting one that only
              exists on the home page. */
body.koda-chrome .bar .wrap,
body.koda-chrome .foot .wrap{ width: min(1240px, 100% - 40px); margin-inline: auto; }
@media (max-width: 640px){
  body.koda-chrome .bar .wrap,
  body.koda-chrome .foot .wrap{ width: min(1240px, 100% - 28px); }
}
body.koda-chrome .skip{
  position: absolute; left: -9999px; top: 0; z-index: 10000;
  background: var(--ink); color: #fff; padding: 14px 22px; font-size: 16px; font-weight: 600;
}
body.koda-chrome .skip:focus{ left: 12px; top: 12px; }
body.koda-chrome .bar img,
body.koda-chrome .foot img{ max-width: 100%; display: block; }
body.koda-chrome .bar a,
body.koda-chrome .foot a,
body.koda-chrome .bar-sheet a,
body.koda-chrome .drawer a{ text-decoration: none; }
body.koda-chrome .bar button,
body.koda-chrome .bar-sheet button,
body.koda-chrome .drawer button,
body.koda-chrome .drawer input{ font: inherit; }
body.koda-chrome .foot ul{ list-style: none; margin: 0; padding: 0; }
body.koda-chrome .drawer h2,
body.koda-chrome .foot h3{
  font-family: var(--font-display); font-weight: 700; line-height: 1.14;
}
/* THE TRACKING IS DECLARED, NOT INHERITED, and it is the one measured
   difference a computed-style diff of the home page against /carpet turned up:
   -0.26px there, -0.312px here, because each page's own h2 rule was setting it.
   A heading in the CHROME must not take its letterfit from whatever stylesheet
   the page underneath happens to ship. */
body.koda-chrome .drawer h2{ color: var(--ink); letter-spacing: -.01em; }

/* ═══════════════════════════════════════════════════════════════════════════
   TOP BAR — "the brass rail"
   The old bar was one flat burgundy strip. This one is a real object: a
   burgundy gradient with grain in it, a warm inner highlight along the top
   edge, a foil hairline along the bottom, and a shadow it casts on the page.
   ═══════════════════════════════════════════════════════════════════════════ */
body.koda-chrome .bar{
  position: fixed; inset: 0 0 auto; z-index: 900;
  height: var(--bar-h);
  background:
    linear-gradient(180deg, rgba(255,255,255,.10) 0 1px, rgba(255,255,255,0) 1px),
    linear-gradient(178deg, var(--ink-lift) 0%, var(--ink-mid) 45%, var(--ink) 100%);
  box-shadow: 0 1px 0 rgba(255,255,255,.06) inset,
              0 10px 30px -12px rgba(13,26,43,.55),
              0 1px 0 var(--gold-deep);
  transition: box-shadow .3s var(--ease);
}
/* Grain, inside the bar rather than over it, so the gradient looks like inked
   paper instead of a CSS ramp. */
body.koda-chrome .bar::before{
  content: ''; position: absolute; inset: 0;
  background-image: var(--grain); opacity: .09; mix-blend-mode: overlay; pointer-events: none;
}
/* The foil hairline. Brightest in the middle, like light along a rail. */
body.koda-chrome .bar::after{
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: linear-gradient(90deg,
    rgba(199,154,58,0) 0%, var(--gold-deep) 12%, var(--gold-lit) 50%, var(--gold-deep) 88%, rgba(199,154,58,0) 100%);
  opacity: .85;
}
/* ── WHAT `.scrolled` IS ALLOWED TO CHANGE (2026-09-11) ─────────────────────
   Jeremy: *"Don't have the top bar resize as the user scrolls on the page
   initially, only pull back the gold review banner. Right now the whole bar
   resizes which looks weird."*

   He is right, and "weird" is precise: six controls were each shrinking on
   their own curve — the bar 76→64, the mark 46→38, the phone medallion 34→30,
   its number 19→18, the Book button's padding and label — so the rail did not
   so much shrink as ripple, every piece arriving at its new size at a slightly
   different moment. A masthead that changes size at all is a masthead that
   moves while you are reading past it.

   THE PENNANT IS THE ONE THING THAT SHOULD MOVE, because it is the one thing
   that is not a control: it hangs BELOW the bar at rest, over the hero, and it
   has to get out of the way of the page. So it retracts into the rail and its
   two faces start taking turns (see the cross-fade below). Everything else
   holds its size, and all that is left of the transition is a deeper shadow —
   which is the bar lifting off the page, not resizing. */
body.koda-chrome .bar.scrolled{ box-shadow: 0 14px 34px -14px rgba(13,26,43,.65), 0 1px 0 var(--gold-deep); }

body.koda-chrome .bar-in{
  height: 100%; display: flex; align-items: center; gap: 12px;
  position: relative; z-index: 2;
}
/* ── THE RAIL'S WIDTH BUDGET (2026-09-14) ───────────────────────────────────
   The bar holds seven objects — medallion, nav, pennant, phone, sign-in, Book
   Online, burger — inside a 1240px wrap, and it had been over that budget for a
   while: at 1440 the content measured 1273 against 1240, so Book Online sat
   about thirty pixels outside the column every other object lines up with, and
   anywhere between 1120 and about 1368 it ran off the screen entirely. The
   medallion is wider than the bare mark was, which turned a quiet overrun into
   a loud one, so the budget is now actually balanced rather than nearly:
     · this gap 20 → 12                      −56
     · .bar-nav a padding 14px → 10px        −32
     · .bar-logo padding 34px → 26px         −16
     · .bar-nav gap and margin                −8
   That lands the rail at about 1237 in a 1240 column. The remaining five pixels
   are the whole margin, which is why NOTHING new goes in this bar without
   measuring `.bar-in.scrollWidth` against its `clientWidth` first. */
@media (max-width: 780px){ body.koda-chrome .bar-in{ gap: 10px; } }
/* ── THE MARK IN THE BAR ────────────────────────────────────────────────────
   Jeremy, 2026-09-10: *"The KODA Logo is in a white box and is so tiny. Can you
   fix that so it is as large as possible while cleanly fitting and without the
   white box (maybe give it a thin white shadow to stand out)."*

   ═══ WHY IT WAS TINY, WHICH IS NOT THE REASON IT LOOKED TINY ═══

   `height: 42px` was doing what it said. The trouble is that koda-logo.png.png
   is a 1200 × 700 canvas and the artwork inside it occupies y 192–485 — 293 of
   those 700 pixels, 42% of the height, floating in transparent margin. So a
   42px box rendered about 17px of actual ink, and then a 12px plaque was drawn
   around the whole 42px including the empty half. The mark was competing with
   its own padding, and losing.

   So the bar uses koda-logo-mark.png: the SAME FILE, cropped to its own alpha
   bounding box with 8px of breathing room (906 × 309). Not a redraw and not a
   re-colour — CLAUDE.md §2 is untouched, because every pixel of artwork is the
   artwork. It simply stops the browser scaling three hundred pixels of nothing.
   The full-canvas original is still what the hero, the emails, the print sheets
   and every other page use; only this one control needed the tight crop.

   ═══ AND WHY THE PLAQUE COULD GO ═══

   The plaque was there because the mark is full-colour on transparency — slate
   letters and a burgundy rule — and burgundy on navy is 1.3:1. Something had to
   sit behind it. But a white rectangle in the corner of a burgundy-gradient bar
   is a patch, not a lockup, and it is the first thing the eye lands on.

   ═══ AND THE NAMEPLATE WENT WITH IT (2026-09-11, second pass) ═══

   Jeremy: *"The logo on the top bar needs the white outline removed and needs
   to have the logo stand out. The white outline is ugly, we don't want to
   impact the visuals, we just need that logo to stand out."*

   FOUR ANSWERS AND ALL FOUR WERE THE SAME ANSWER. A white plaque, then three
   blurred white shadows, then a die-cut keyline, then a full-height cream
   nameplate: a box, a cloud, a hairline and a panel, every one of them a pale
   ground slipped between the artwork and the navy. Jeremy has now rejected all
   four in the same words each time, which is the page telling us the ground was
   never the fix.

   SO THERE IS NO GROUND. The mark is REVERSED instead — struck in one ink, the
   brand's own cream, straight onto the night chrome, the way a reversed lockup
   is set on any dark masthead. `feColorMatrix` keeps the alpha channel exactly
   as the file draws it and replaces only the RGB, so the artwork is the
   artwork: every curve, every letterform, the mascot's silhouette and his
   vacuum, at the file's own proportions. Nothing is redrawn and nothing is
   approximated — CLAUDE.md §2 is about not RECREATING the mark, and a one-ink
   reverse of the real file is the thing brand books print on the page after the
   full-colour one.

   AND IT IS THE HIGHEST-CONTRAST THING IN THE BAR. Cream on navy measures about
   14:1, against 1.3:1 for the burgundy rule the plaque existed to rescue. The
   mark no longer needs help standing out; it is what everything else in the rail
   is quieter than.

   THE SAME TREATMENT RUNS IN THE FOOTER. One mark, one rule, both ends of the
   page — see .foot-logo. */
/* ═══ AND NOW IT IS THE REAL MARK AGAIN (2026-09-14) ═══
   Jeremy: *"Find a way to get our logo in the top bar, not the white out
   version. Don't put a flat box behind it."*

   The mark is slate letters, a burgundy rule and a full-colour mascot, and on
   navy chrome burgundy measures 1.3:1 — so the artwork genuinely does need
   light behind it. A RECTANGLE of light was the only shape that had ever been
   tried, so the first answer here was a rectangle's opposite: a radial pool of
   cream with no edge anywhere, dissolving into the navy before it reached any
   boundary.

   ═══ AND A POOL OF LIGHT IS NOT AN OBJECT (2026-09-14, same day) ═══
   Jeremy: *"The top bar has our logo with a white oval behind it. This really
   makes it feel cheap and I don't know why. Can you help that feel classier?
   Maybe a solid oval with a textured gold outline or similar?"*

   HE NAMED THE REASON IN THE SENTENCE HE SAID HE DIDN'T HAVE. An edgeless pool
   of white on a dark rail has exactly one referent: a soft eraser pass, or the
   halo behind a logo someone key-lined out of a JPEG. It reads as damage to the
   bar rather than as a thing sitting on it — because a real object has a rim,
   and the rim is what says somebody MADE it.

   SO IT IS A MEDALLION NOW, and it is struck from the same metal as everything
   else gold on this page. The manufacture is the review pennant's, line for
   line (see .seal): a five-stop foil ramp that runs bright at the crown, down
   through the mid-tone, back up across a specular band and into the deepest
   tone at the foot; a fine guilloche hatch over it at low opacity so the gold
   is a surface and not a swatch; a white crown along the top edge and a dark
   one along the bottom, which is what gives a rim its thickness; and a shadow
   it throws onto the rail, so it sits ON the bar rather than in it.

   Inside the rim is the FACE — the brand cream, solid, with a top-down sheen
   and an inset shade under the rim, the way an enamel face sits down inside its
   bezel. Two dark-gold hairlines, one against the navy and one against the
   cream, keep the ring from bleeding into either. The mark is then the real
   full-colour file at its own proportions, in daylight, exactly as before.

   ═══ AND THEN THE ELLIPSE CUT THE G OFF (2026-09-14, later the same day) ═══
   Jeremy: *"fix this oval so the G isn't cut off and it feels more
   intentionally designed. It may not need an oval, it just can't be a boring
   box. It needs to feel luxurious and classy and clean and professional."*

   THE ELLIPSE WAS NEVER GOING TO HOLD THIS MARK, and the arithmetic says so.
   The mark rendered 134.82 x 45.99 inside a 186.81 x 65.96 oval, so its corner
   sat at

       (67.41 / 93.41)^2 + (22.99 / 32.98)^2 = 1.0067

   — just over 1, which means just OUTSIDE the curve. The face fell away behind
   the last glyph of CLEANING and the G was left standing on navy. Closing that
   gap needs about 41% overwidth on a 2.9:1 mark; the padding bought 39%, and
   buying the other 2% costs pixels on the one rail where width is scarcest.

   SO IT IS A STRUCK PLATE NOW — the same foil, the same cream face, the same
   two hairlines, cut to a shape that can actually hold a wordmark. The corners
   are chamfered at 45 degrees, which is the one move that separates a plate
   from the box Jeremy ruled out: a cut corner is a MACHINING mark, the thing
   an engraver does to a brass nameplate so it has no point to catch on. It
   costs no width at all — the plate is 175 x 66, twelve pixels narrower than
   the oval that was clipping — and it holds the mark with 20px of air at the
   ends and 10px top and foot, none of it borrowed from the glyphs.

   The reverse filter is still declared in index.html and still used — the
   FOOTER mark keeps it (.foot-logo), where the ground is navy by design and
   there is no photograph or daylight anywhere near it. */
body.koda-chrome .bar-logo,
body.koda-chrome .foot-logo{
  flex-shrink: 0; position: relative;
  display: flex; align-items: center; justify-content: center;
  /* THE PADDING IS THE PLATE. A straight-sided shape hugs a 2.9:1 mark in a way
     no closed curve can: 20px of air at the ends, 10px top and foot, and the
     whole plate is 175 x 66 — twelve pixels NARROWER than the ellipse that was
     still clipping the last glyph of CLEANING. */
  padding: 10px 20px;
  /* THE CUT CORNERS, AND THE ONE PIECE OF ARITHMETIC IN THEM.
     `--plate-cut` is the length of the 45-degree cut on the rim. The face is
     inset 4px inside the rim, and offsetting a 45-degree cut inward by d
     shortens its leg by d(2 - sqrt2) = 0.586d — 2.34px at d = 4. Without that
     correction the gold band pinches to a point at every corner, which is the
     one thing that would say "clip-path" out loud. */
  --plate-cut: 11px;
  --plate-inset: 4px;
  --plate-cut-in: calc(var(--plate-cut) - 2.34px);
}
/* ── THE SHADOW MOVED ONTO THE SHAPE THAT CASTS IT (2026-09-16) ─────────────
   A CLIPPED SHAPE CANNOT CAST A BOX-SHADOW, so the plate's shadow has always
   been a `filter: drop-shadow`. It used to sit on the ANCHOR, and that is the
   line being changed here.

   Jeremy: *"On the repair page, when we loaded it for a second or third time
   the logo on the top bar glitched to a weird white/green/pink display. Fixed
   itself upon refresh."*

   WHITE, GREEN AND PINK ARE NOT COLOURS ANY STYLESHEET IN THIS REPO NAMES.
   Nothing in the plate is green or pink; the mark is slate, burgundy and cream
   on gilt. A garbled triplet that appears on a warm load and goes away on a
   hard one is not a style, it is a COMPOSITED LAYER handed back a raster that
   was never painted into — the GPU showing whatever was in that texture.

   AND THE LAYER IT WAS SHOWING IS THIS ONE. `filter` on the anchor made the
   anchor a filter root, and everything inside it — two `clip-path` pseudos
   carrying six background layers between them, plus the PNG — had to be
   rasterised into one offscreen surface before the shadow could be taken from
   it. That surface is the largest and most expensive thing in the bar, it is
   inside a `position: fixed` element that is already its own blending group
   (`.bar::before`, `mix-blend-mode: overlay`), and it is the only thing on any
   of these pages built that way.

   SO THE FILTER GOES WHERE IT BELONGS: on the rim, which is the silhouette the
   shadow is meant to follow. `clip-path` is applied before `filter`, so the
   drop still traces the chamfered corners exactly as it did — but the anchor
   stops being a filter root, and the mark and the face are composited as
   ordinary painted content instead of being pulled through an offscreen
   surface with them.

   THIS IS A MITIGATION, NOT A REPRODUCTION. The fault is a driver-level
   raster-cache miss and it did not reproduce here across repeated warm loads
   of /carpet-repair. What can be said is that the pattern it needs — a filter
   root wrapping clipped, multi-layer pseudo-elements inside a fixed blending
   group — is gone. If it ever comes back, the next thing to take off is the
   `mix-blend-mode: overlay` on `.bar::before`. */
body.koda-chrome .bar-logo::before,
body.koda-chrome .foot-logo::before{
  filter:
    drop-shadow(0 1px 1px rgba(9,16,26,.46))
    drop-shadow(0 6px 13px rgba(9,16,26,.44));
  transition: filter .28s var(--ease);
}
/* THE RIM — the same struck foil as the review pennant and the wax seal, so
   every gold object in this chrome comes off one metal. */
body.koda-chrome .bar-logo::before,
body.koda-chrome .foot-logo::before{
  content: ''; position: absolute; inset: 0; z-index: 0;
  pointer-events: none;
  clip-path: polygon(
    var(--plate-cut) 0, calc(100% - var(--plate-cut)) 0,
    100% var(--plate-cut), 100% calc(100% - var(--plate-cut)),
    calc(100% - var(--plate-cut)) 100%, var(--plate-cut) 100%,
    0 calc(100% - var(--plate-cut)), 0 var(--plate-cut));
  background:
    /* the guilloche: two hatches crossing at a shallow angle, both barely there */
    repeating-linear-gradient(116deg, rgba(255,255,255,.20) 0 1px, rgba(255,255,255,0) 1px 4px),
    repeating-linear-gradient( 62deg, rgba(74,52,12,.15) 0 1px, rgba(74,52,12,0) 1px 5px),
    linear-gradient(166deg,
      #f7ecc6 0%, #e2c67f 13%, #c9a44c 36%,
      #dcbe74 55%, #b98f34 78%, #8a6a24 100%);
  box-shadow:
    inset 0 0 0 1px rgba(74,52,12,.50),      /* the hairline against the navy   */
    inset 0 1.5px 0 rgba(255,255,255,.78),   /* the crown catches the light     */
    inset 0 -1.5px 0 rgba(74,52,12,.62);     /* and the foot gathers the shade  */
}
/* THE FACE, set down inside the rim — brand cream, solid, lit from above. */
body.koda-chrome .bar-logo::after,
body.koda-chrome .foot-logo::after{
  content: ''; position: absolute; inset: var(--plate-inset); z-index: 1;
  pointer-events: none;
  clip-path: polygon(
    var(--plate-cut-in) 0, calc(100% - var(--plate-cut-in)) 0,
    100% var(--plate-cut-in), 100% calc(100% - var(--plate-cut-in)),
    calc(100% - var(--plate-cut-in)) 100%, var(--plate-cut-in) 100%,
    0 calc(100% - var(--plate-cut-in)), 0 var(--plate-cut-in));
  background: linear-gradient(172deg, #fffefb 0%, #fbf8f3 48%, #f1eade 100%);
  box-shadow:
    inset 0 0 0 1px rgba(74,52,12,.34),      /* the hairline against the cream  */
    inset 0 3px 5px -1px rgba(74,52,12,.26), /* the rim's own shadow, falling in */
    inset 0 -1px 0 rgba(255,255,255,.96);
}
body.koda-chrome .bar-logo img,
body.koda-chrome .foot-logo img{
  position: relative; z-index: 2;
  height: 46px; width: auto; transition: height .3s var(--ease);
}
/* THE WHOLE PLATE LIFTS ON HOVER — rim, face and mark together, one object.
   The drop is on the rim now (see THE SHADOW MOVED ONTO THE SHAPE THAT CASTS
   IT), so the hover has to reach it there; the trigger is still the anchor,
   because the rim is a pseudo-element and cannot be hovered on its own. */
body.koda-chrome .bar-logo:hover::before{
  filter:
    drop-shadow(0 1px 1px rgba(9,16,26,.46))
    drop-shadow(0 10px 20px rgba(9,16,26,.55));
}
body.koda-chrome .bar-logo:hover::before{
  box-shadow:
    inset 0 0 0 1px rgba(74,52,12,.50),
    inset 0 1.5px 0 rgba(255,255,255,.94),
    inset 0 -1.5px 0 rgba(74,52,12,.62);
}
body.koda-chrome .bar-logo:focus-visible{ outline: 3px solid var(--gold-lit); outline-offset: 3px; }
/* ── AND ON A PHONE THE RAIL HAS 362 PIXELS ─────────────────────────
   A 390px screen gives the wrap 362, and the pennant alone takes 118 of them
   before the call button and the burger have had any. So the plate steps down
   twice — 175 x 66 on a desktop, 124 x 50 from a tablet down, 109 x 45 on the
   narrowest phones — and it is the same object at the same proportions each
   time, just held closer. The cut shrinks with it, because a corner cut that
   stays 11px while the plate loses a quarter of its height stops reading as a
   detail and starts reading as a hexagon. */
@media (max-width: 780px){
  body.koda-chrome .bar-logo,
  body.koda-chrome .foot-logo{
    padding: 8px 14px;
    --plate-cut: 8px; --plate-inset: 3px;
    --plate-cut-in: calc(var(--plate-cut) - 1.76px);
  }
  body.koda-chrome .bar-logo img,
  body.koda-chrome .foot-logo img{ height: 34px; }
}
@media (max-width: 400px){
  body.koda-chrome .bar-logo,
  body.koda-chrome .foot-logo{
    padding: 7px 12px;
    --plate-cut: 7px; --plate-inset: 3px;
    --plate-cut-in: calc(var(--plate-cut) - 1.76px);
  }
  body.koda-chrome .bar-logo img,
  body.koda-chrome .foot-logo img{ height: 31px; }
}

body.koda-chrome .bar-nav{ display: flex; gap: 2px; margin-left: 6px; }
body.koda-chrome .bar-nav a{
  color: rgba(255,255,255,.86); font-size: 16px; font-weight: 500;
  padding: 9px 10px; border-radius: 8px; position: relative;
  white-space: nowrap;          /* "Book Online" is one item, not two lines */
  transition: color .18s, background .18s;
}
body.koda-chrome .bar-nav a:hover{ color: #fff; background: rgba(255,255,255,.09); }
body.koda-chrome .bar-spacer{ margin-left: auto; }

/* ── THE REVIEW FLAG ────────────────────────────────────────────────────────
   Jeremy, fourth pass: "Go back to the old shape of the google review tab but
   actually design to it. Right now it's just flat text in a box that is half
   whitespace. Change that whole flag to gold, textured, 3d, utilizing the whole
   flag to clearly send the message. 5.0 Stars, 1,200+ reviews."

   So: the pennant shape returns, and the whole object is struck metal.

   HOW THE GOLD IS BUILT. One flat #c9a44c reads as a yellow rectangle, which is
   what "flat text on an empty background" meant. Real foil has a light source,
   so the fill is a five-stop vertical ramp that runs bright at the crown, dips
   through the mid-tone, brightens again across the middle (the specular band a
   curved metal surface throws), then falls to the deepest tone at the fold.
   Over that sits a fine diagonal hatch at 6% — the guilloche you see on a
   minted seal — and the page grain. Neither is nameable at a glance; together
   they stop the surface reading as a swatch.

   HOW THE DEPTH IS BUILT. Four shadows on one element:
     · inset top      a 2px white crown, so the flag catches light on its edge
     · inset sides    two hairlines of dark gold, giving the strip thickness
     · inset bottom   a deep shade that gathers into the fold of the V
     · outer          the shadow it throws onto the photograph beneath
   The ::after triangle is the fold itself — the underside of the pennant,
   darker than the face, which is what makes the V read as folded rather than
   cut.

   HOW THE SPACE IS USED. Three tiers filling the full height, each doing one
   job: the star row states the rating in the language everyone already reads,
   the numeral is the largest glyph in the chrome, and the count is the proof.
   Nothing is centred in a void. */
body.koda-chrome .seal{
  position: relative; z-index: 4; flex-shrink: 0;
  align-self: stretch;
  /* THE OVERHANG. Four tiers of type need real height, so the flag drops well
     past the bar. A stretched flex item's cross size is the line height minus
     its margins, so -78px makes it 78px taller than the 76px bar. Nothing
     clips it: .bar has no overflow rule, deliberately. The matching
     padding-bottom keeps the type off the pennant's point. */
  margin-bottom: -78px;
  width: 150px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px;
  padding: 6px 10px 40px;
  text-decoration: none;
  background:
    linear-gradient(180deg,
      #f7ecc6 0%, #e2c67f 12%, #c9a44c 34%,
      #dcbe74 54%, #b98f34 76%, #8a6a24 100%);
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 26px), 50% 100%, 0 calc(100% - 26px));
  box-shadow:
    inset 0  2px 0 rgba(255,255,255,.72),
    inset  1px 0 0 rgba(255,255,255,.30),
    inset -1px 0 0 rgba(120,92,28,.55),
    inset 0 -30px 30px -24px rgba(74,52,12,.75);
  filter: drop-shadow(0 12px 18px rgba(0,0,0,.5));
  transition: transform .22s var(--ease), filter .22s var(--ease),
              margin-bottom .3s var(--ease), padding .3s var(--ease);
}
body.koda-chrome .seal:hover{
  transform: translateY(2px);
  filter: drop-shadow(0 16px 24px rgba(0,0,0,.6));
}
body.koda-chrome .seal:focus-visible{ outline: 3px solid var(--paper); outline-offset: -4px; }

/* The texture: a fine diagonal hatch plus the page grain, both barely there. */
body.koda-chrome .seal::before{
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background-image:
    repeating-linear-gradient(135deg,
      rgba(255,255,255,.16) 0 1px, rgba(255,255,255,0) 1px 5px),
    var(--grain);
  background-size: auto, 120px 120px;
  opacity: .38;
  mix-blend-mode: overlay;
}
/* The fold: the underside of the pennant, darker than its face. */
body.koda-chrome .seal::after{
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 34px;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(74,52,12,0) 0%, rgba(74,52,12,.42) 100%);
}

/* ── The two faces ──────────────────────────────────────────────────────────
   Every glyph on the pennant is struck INTO the metal: a light lower edge and a
   dark upper one, which is what a stamped surface does to a letter.

   The four tiers are grouped into TWO FACES — the rating (5.0 over its stars)
   and the proof (the count over the word "Reviews") — because once the flag
   retracts there is only room for one of them and they have to be able to take
   turns. At rest both are shown, stacked, exactly as before. */
body.koda-chrome .seal-face{
  display: flex; flex-direction: column; align-items: center;
  position: relative; z-index: 1;
}
body.koda-chrome .seal-score,
body.koda-chrome .seal-count{
  font-family: var(--font-display); font-weight: 800;
  color: #2c2109; letter-spacing: -.02em; line-height: .98;
  font-variant-numeric: tabular-nums; white-space: nowrap;
  text-shadow: 0 1px 0 rgba(255,255,255,.5), 0 -1px 0 rgba(74,52,12,.35);
}
body.koda-chrome .seal-score{ font-size: 34px; }
body.koda-chrome .seal-stars{
  font-size: 15px; letter-spacing: 2.5px; line-height: 1.25;
  color: #4a340c;
  text-shadow: 0 1px 0 rgba(255,255,255,.45);
}
/* A hairline between the rating and the count: two facts, one badge. */
body.koda-chrome .seal-face-count{
  margin-top: 6px; padding-top: 7px;
  border-top: 1px solid rgba(74,52,12,.34);
  width: 78%;
}
body.koda-chrome .seal-count{ font-size: 25px; text-align: center; }
body.koda-chrome .seal-lbl{
  font-size: 12px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: #4a340c; white-space: nowrap; line-height: 1.2;
  text-shadow: 0 1px 0 rgba(255,255,255,.4);
}

/* ── THE FLAG RETRACTS WHEN THE PAGE MOVES ─────────────────────────────────
   Jeremy: "when I scroll, the 1200 reviews should hide behind tiles/items."

   At rest the pennant is meant to hang past the bar and over the hero — that
   is the design. The problem is what it does once the page is moving: it lives
   inside .bar (z-index 900), so its 78px of overhang was painting on top of
   every card, tile and heading that scrolled underneath it, all the way down
   the page. It cannot be sent behind that content while staying above the bar
   it hangs off — one element cannot be on both sides of the chrome — so it
   comes home instead: on scroll the flag pulls its overhang up into the
   shrunken bar and nothing of it is left over the page.

   ═══ WHAT SURVIVES THE RETRACTION (rebuilt 2026-09-10) ═══

   Jeremy: "when it collapses can we have it say 5.0 with the stars below
   instead of the stars with 1200 reviews? I'd rather we focus on 5.0 rating
   (or when it collapses is there a way to have it slowly fade back and forth
   between the two)".

   Both, and in that order of priority. The retracted flag holds ONE face at a
   time in one grid cell, and the RATING is the one it opens on, the one it
   returns to, and the one it holds longest — 5.0 over its stars, which is the
   claim, in the language everybody already reads. The count fades in behind it
   for a shorter beat and fades back out. Nothing moves; only opacity changes,
   so there is no reflow in the chrome while the page is scrolling.

   THE SIZES ARE STILL OVER THE FLOOR. 26px, 13px, 19px and 11.5px — every one
   at or above CLAUDE.md §4.1's 12px web floor except the letter-spaced
   all-caps "REVIEWS", which sits with the other micro-labels in this bar.

   AND IT STOPS FOR ANYONE WHO ASKED IT TO. Under prefers-reduced-motion the
   animation is dropped entirely and the flag simply shows the rating — the
   half Jeremy said he would rather focus on — with the count hidden. A badge
   that pulses in the corner of every page is exactly what that setting is
   for. */
/* ── AND THE DRAWER RETRACTS IT TOO (2026-09-14) ───────────────────────
   Jeremy: *"When a user clicks 'sign-in' and the signin UI comes up, we need to
   retract the review banner in the top bar — as it sits, when a user is at the
   top of the page and clicks sign-in, the banner hangs over the sign-in
   options."*

   THE FLAG IS 78px TALLER THAN THE BAR, ON PURPOSE (see THE OVERHANG above) —
   and the drawer opens from exactly `top: var(--bar-h)`, which is the band the
   overhang occupies. At the top of the page the two are in the same place, and
   the pennant is the one in front.

   It is the same retraction the page already performs on scroll, so it is the
   same rule: `:is(.scrolled, .drawer-open)`. The bar carries `.drawer-open`
   for as long as the drawer is down (openDrawer/closeDrawer in home.js), the
   flag folds into the chrome over the same .3s it uses on scroll, and it comes
   back the moment the drawer closes — unless the page has been scrolled
   meanwhile, in which case `.scrolled` holds it retracted and nothing jumps.
   Every declaration below is shared by both states; none of them is new. */
body.koda-chrome .bar:is(.scrolled, .drawer-open) .seal{
  margin-bottom: 0;
  padding: 4px 10px 15px;
  display: grid; place-items: center;
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 13px), 50% 100%, 0 calc(100% - 13px));
}
body.koda-chrome .bar:is(.scrolled, .drawer-open) .seal::after{ height: 18px; }
/* Both faces occupy the same cell, so the flag never changes size as they
   swap and the bar never reflows under a scrolling page. */
body.koda-chrome .bar:is(.scrolled, .drawer-open) .seal-face{
  grid-area: 1 / 1; align-self: center;
  animation: sealFace 11s var(--ease) infinite;
}
body.koda-chrome .bar:is(.scrolled, .drawer-open) .seal-face-rating{ animation-name: sealFaceA; }
body.koda-chrome .bar:is(.scrolled, .drawer-open) .seal-face-count{
  animation-name: sealFaceB;
  margin-top: 0; padding-top: 0; border-top: 0; width: auto;
}
body.koda-chrome .bar:is(.scrolled, .drawer-open) .seal-score{ font-size: 26px; }
body.koda-chrome .bar:is(.scrolled, .drawer-open) .seal-stars{
  font-size: 13px; letter-spacing: 2px; line-height: 1.15; margin-top: 1px;
}
body.koda-chrome .bar:is(.scrolled, .drawer-open) .seal-count{ font-size: 19px; }
body.koda-chrome .bar:is(.scrolled, .drawer-open) .seal-lbl{ font-size: 11.5px; margin-top: 1px; }

/* The rating holds roughly seven of every eleven seconds; the count gets the
   rest. The fades overlap by design — a beat of blank metal in the middle of a
   swap reads as a bug. */
@keyframes sealFaceA{
   0%   { opacity: 1; }
  52%   { opacity: 1; }
  60%   { opacity: 0; }
  90%   { opacity: 0; }
  98%   { opacity: 1; }
 100%   { opacity: 1; }
}
@keyframes sealFaceB{
   0%   { opacity: 0; }
  52%   { opacity: 0; }
  62%   { opacity: 1; }
  88%   { opacity: 1; }
  98%   { opacity: 0; }
 100%   { opacity: 0; }
}
@media (prefers-reduced-motion: reduce){
  body.koda-chrome .bar:is(.scrolled, .drawer-open) .seal-face{ animation: none; }
  body.koda-chrome .bar:is(.scrolled, .drawer-open) .seal-face-rating{ opacity: 1; }
  body.koda-chrome .bar:is(.scrolled, .drawer-open) .seal-face-count{ opacity: 0; visibility: hidden; }
}

@media (max-width: 1080px){
  body.koda-chrome .seal{ width: 136px; }
  body.koda-chrome .seal-score{ font-size: 30px; }
  body.koda-chrome .seal-count{ font-size: 22px; }
}
@media (max-width: 640px){
  body.koda-chrome .seal{ width: 118px; margin-bottom: -66px; padding-bottom: 34px; }
  body.koda-chrome .seal-score{ font-size: 25px; }
  body.koda-chrome .seal-stars{ font-size: 12px; letter-spacing: 1.6px; }
  body.koda-chrome .seal-face-count{ margin-top: 4px; padding-top: 5px; }
  body.koda-chrome .seal-count{ font-size: 19px; }
  body.koda-chrome .seal-lbl{ font-size: 10px; letter-spacing: .12em; }
}

/* ── THE PHONE NUMBER ───────────────────────────────────────────────────
   Jeremy, 2026-09-10: "Fix the appearance of the phone number button — that is
   the ugliest part of this page." He was right, and the reason is worth writing
   down: it was a TRANSLUCENT WHITE PILL WITH A WHITE BORDER, copied from the
   sign-in button beside it. Sign-in is a label; a phone number is a FACT, and
   the two do not want the same shape. On night chrome a 20%-white outline over
   a 14%-white fill has no edge — it reads as a smudge with digits in it — and
   the icon and the number shared one line with nothing to say which was which.

   SO IT IS A LOCKUP, NOT A PILL. A gilt-ringed medallion holds the handset;
   beside it a small gilt label sits over the number in the display face, on two
   tiers. That is deliberately the same construction as the review pennant three
   inches to its left, which is what makes the right-hand end of the bar read as
   one designed group rather than three borrowed shapes.

   NO BOX AT ALL. The only line it owns is a gilt hairline that draws itself
   under the number on hover — the same foil as the bar's own bottom edge, so
   the hover looks like the object was always part of the rail. */
body.koda-chrome .bar-phone{
  display: inline-flex; align-items: center; gap: 11px;
  padding: 6px 10px 6px 6px; border-radius: 12px;
  color: #fff; white-space: nowrap; position: relative;
  transition: transform .16s var(--ease);
}
body.koda-chrome .bar-phone-ico{
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center;
  background: radial-gradient(120% 120% at 50% 0%, rgba(226,198,127,.30), rgba(201,164,76,.12));
  border: 1px solid rgba(201,164,76,.55);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.28), 0 3px 8px -4px rgba(0,0,0,.6);
  color: var(--gold-lit);
  transition: border-color .18s, color .18s, box-shadow .18s;
}
body.koda-chrome .bar-phone-txt{ display: flex; flex-direction: column; line-height: 1.05; }
/* 12px, which is CLAUDE.md §4.1's absolute web floor and not a pixel under it.
   The review pennant's own labels beside this sit at 10 and 11.5 — they are a
   struck-metal design that shipped that way and are not being restyled here —
   but nothing NEW on this page gets to go under the floor, least of all a label
   on the control a customer taps to phone us. The readable content of this
   lockup is the 20px number beneath it either way. */
body.koda-chrome .bar-phone-lbl{
  font-family: var(--font-body); font-size: 12px; font-weight: 600;
  letter-spacing: .15em; text-transform: uppercase;
  color: rgba(226,198,127,.92); margin-bottom: 3px;
}
body.koda-chrome .bar-phone-num{
  font-family: var(--font-display); font-size: 20px; font-weight: 700;
  color: #fff; letter-spacing: -.005em;
  /* The hairline lives on the NUMBER rather than on the anchor, so it is
     exactly as wide as the number and never as wide as medallion-plus-number. */
  background: linear-gradient(90deg, var(--gold-deep), var(--gold-lit), var(--gold-deep))
              0 100% no-repeat;
  background-size: 0 2px;
  padding-bottom: 3px;
  transition: background-size .28s var(--ease);
}
body.koda-chrome .bar-phone:hover{ transform: translateY(-1px); }
body.koda-chrome .bar-phone:hover .bar-phone-num{ background-size: 100% 2px; }
body.koda-chrome .bar-phone:hover .bar-phone-ico{
  border-color: var(--gold-lit); color: #fff;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4), 0 6px 14px -5px rgba(0,0,0,.7);
}
body.koda-chrome .bar-phone:active{ transform: translateY(1px); }
/* The bar shrinks on scroll; the lockup goes with it rather than crowding the
   rail it sits on. */

/* ── BOOK ONLINE — the bar's one action ─────────────────────────────────
   Jeremy: "The 'Book Online' button — shift that to the right of 'Sign In' and
   make it a red button like the 'Continue' button so it stands out."

   Same burgundy, same gradient, same press as .btn-primary inside the card, so
   the thing that starts a booking in the chrome and the thing that advances one
   in the form are recognisably one object. Nocturne's rule holds: burgundy is
   the ACTION colour and it is nothing else on this page, which is exactly why
   one burgundy control in a navy bar cannot be missed.

   AND IT BREATHES. Jeremy: "Have the 'Book Now' button very lightly and very
   slowly pulse." SIX SECONDS a cycle, and what moves is the GLOW, not the
   button: a transform would shift a click target under somebody's cursor, and a
   pulsing size next to a fixed sign-in button reads as a rendering fault rather
   than an invitation.

   ═══ AND THE HALO IS GOLD NOW (2026-09-16) ═══
   Jeremy: *"The Book Online button at the top — change the pulse to be the gold
   colour (keep it textured with depth) and have it be slightly more intense."*

   BURGUNDY ON NAVY WAS A GLOW NOBODY COULD SEE. A 30%-opacity burgundy ring
   around a burgundy button, on a navy rail, is three dark values inside about
   four points of each other — the ring existed and measured almost nothing.
   Gilt is the one ink in this chrome that is LIGHTER than the bar, so the halo
   finally reads as light coming off the button rather than as the button
   swelling.

   "TEXTURED WITH DEPTH" IS THE THREE-PART SHADOW, AND IT STAYS. The button
   keeps its cast shadow underneath and its white crown along the top edge —
   the two things that make it an object sitting on the rail — and the pulse is
   added to them rather than replacing them. What is new is that the halo is now
   TWO rings, not one: a tight 9px ring at .42 that gives the glow an edge, and
   a soft 24px bloom at .26 behind it that gives it a falloff. One ring at high
   opacity is a keyline; a ring and a bloom is light.

   "SLIGHTLY MORE INTENSE" IS A FLOOR, NOT ONLY A PEAK. The old cycle returned
   to nothing, so for most of every six seconds there was no ring at all. It now
   rests at a faint 2px gilt line and breathes up from there, which is what
   makes the movement read as steady rather than as a blink. */
body.koda-chrome .bar-book{
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-body); font-size: 16px; font-weight: 700;
  color: #fff; padding: 11px 22px; border-radius: 10px; white-space: nowrap;
  background: linear-gradient(180deg, var(--act-hi) 0%, var(--act) 58%, var(--act) 100%);
  transition: transform .15s var(--ease), background .2s;
  animation: barBookPulse 6s var(--ease) infinite;
}
@keyframes barBookPulse{
   0%  { box-shadow: 0 2px 3px rgba(16,24,36,.28), inset 0 1px 0 rgba(255,255,255,.22),
                     0 0 0 2px rgba(201,164,76,.16), 0 0 10px 0 rgba(201,164,76,.10); }
  45%  { box-shadow: 0 2px 3px rgba(16,24,36,.28), inset 0 1px 0 rgba(255,255,255,.22),
                     0 0 0 9px rgba(201,164,76,.42), 0 0 24px 6px rgba(201,164,76,.26); }
  90%  { box-shadow: 0 2px 3px rgba(16,24,36,.28), inset 0 1px 0 rgba(255,255,255,.22),
                     0 0 0 2px rgba(201,164,76,.16), 0 0 10px 0 rgba(201,164,76,.10); }
 100%  { box-shadow: 0 2px 3px rgba(16,24,36,.28), inset 0 1px 0 rgba(255,255,255,.22),
                     0 0 0 2px rgba(201,164,76,.16), 0 0 10px 0 rgba(201,164,76,.10); }
}
/* The resting ring is what the button wears when the animation never runs, so
   the control looks the same in both worlds rather than losing its edge
   entirely for the people who asked for less motion. */
@media (prefers-reduced-motion: reduce){
  body.koda-chrome .bar-book{
    animation: none;
    box-shadow: 0 2px 3px rgba(16,24,36,.28), inset 0 1px 0 rgba(255,255,255,.22),
                0 0 0 2px rgba(201,164,76,.22), 0 0 10px 0 rgba(201,164,76,.12);
  }
}
body.koda-chrome .bar-book:hover{
  transform: translateY(-2px);
  background: linear-gradient(180deg, var(--act-hi) 0%, var(--act-hi) 100%);
}
body.koda-chrome .bar-book:active{ transform: translateY(1px); }
/* On the phone sheet the same action keeps the same colour — a menu whose one
   burgundy row is Book Online tells you what the menu is for. */
body.koda-chrome .bar-sheet a.sheet-book{
  color: #fff; font-weight: 700;
  background: linear-gradient(180deg, var(--act-hi), var(--act));
}

body.koda-chrome .bar-signin{
  display: inline-flex; align-items: center; gap: 8px;
  /* "Sign in" is TWO WORDS AND ONE CONTROL. The rail is a flex row of six
     things and this is the only label in it that can break; once the mark grew
     to 46px (see THE MARK IN THE BAR) it did, and a two-line "Sign / in" beside
     a one-line "Book Online" reads as a layout that gave up. The other labels
     already carry this; it was the one that did not. */
  white-space: nowrap; flex-shrink: 0;
  font-size: 16px; font-weight: 600; color: rgba(255,255,255,.9);
  background: none; border: 1px solid rgba(255,255,255,.24);
  padding: 10px 16px; border-radius: 10px; cursor: pointer;
  transition: background .18s, color .18s, border-color .18s;
}
body.koda-chrome .bar-signin:hover{ background: rgba(255,255,255,.12); color: #fff; border-color: rgba(255,255,255,.44); }
body.koda-chrome .bar-signin svg{ transition: transform .28s var(--ease); }
body.koda-chrome .bar-signin[aria-expanded="true"] svg.chev{ transform: rotate(180deg); }

body.koda-chrome .bar-burger{
  display: none; width: 46px; height: 42px; border: 1px solid rgba(255,255,255,.24);
  background: none; border-radius: 10px; cursor: pointer; padding: 11px 11px;
  flex-direction: column; justify-content: space-between;
}
body.koda-chrome .bar-burger span{ display: block; height: 2px; background: #fff; border-radius: 2px; transition: transform .25s var(--ease), opacity .2s; }
body.koda-chrome .bar-burger.open span:nth-child(1){ transform: translateY(9px) rotate(45deg); }
body.koda-chrome .bar-burger.open span:nth-child(2){ opacity: 0; }
body.koda-chrome .bar-burger.open span:nth-child(3){ transform: translateY(-9px) rotate(-45deg); }

/* ── WHERE THE NAV LEAVES, THE MENU ARRIVES (2026-09-14) ────────────────────
   The rail needs about 1235px; the wrap is `min(1240, 100% - 40)`, so the nav
   fits at 1280 and wider and at NO narrower width — the column stops growing at
   1240 no matter how wide the window gets, so this is a fit test, not a taste
   one. It used to give up at 1120, which was 150px of wishful thinking.

   AND THE BURGER NOW ARRIVES AT THE SAME MOMENT. It used to wait for 780, so
   every window between 781 and 1120 had no nav and no menu at all — the four
   sections were reachable only by scrolling past them. One breakpoint for both
   halves means there is never a width with neither. */
@media (max-width: 1279px) {
  body.koda-chrome .bar-nav{ display: none; }
  body.koda-chrome .bar-burger{ display: flex; }
}
@media (max-width: 900px) {
  body.koda-chrome .medal-txt{ display: none; }
  body.koda-chrome .medal{ padding: 5px; }
}
/* Between 780 and 1000 the bar is logo · pennant · phone · sign-in · Book, which
   is four controls in the room for three. Sign-in is the one a returning
   customer looks for deliberately, so it is the one that can afford to become a
   row in the menu instead. */
@media (max-width: 1000px) { body.koda-chrome .bar-signin{ display: none; } }
@media (max-width: 780px) {
  /* The NUMBER survives on a phone — it is the one control a visitor might want
     before anything else has loaded. The label over it does not: on a 375px bar
     "Call The Office" is what pushes Book Online off the end. */
  body.koda-chrome .bar-phone-lbl{ display: none; }
  body.koda-chrome .bar-phone{ padding: 4px; gap: 8px; }
  body.koda-chrome .bar-phone-num{ font-size: 17px; }
  body.koda-chrome .bar-book{ padding: 9px 14px; font-size: 15px; }
  :root{ --bar-h: 68px; }
}
/* ── BOOK ONLINE LEAVES THE BAR AT 680 NOW, NOT 560 (2026-09-14) ────────────
   AND IT IS NOT A RETREAT. At 600px the rail is a medallion, a 118px pennant,
   the number, a burgundy button and a menu, and they had already used every
   pixel of it before the rim arrived — the button was running about fourteen
   pixels past the right-hand edge at 600 even with the bare mark. It does not
   vanish: it is the FIRST row of the menu and the only burgundy thing in it
   (.bar-sheet a.sheet-book). And on a phone or a small tablet the hero's
   booking card is the first thing under the headline anyway, so "book online"
   is a scroll rather than a destination.

   THE NUMBER IS WHAT IT GIVES ITS ROOM TO, deliberately. Of the two, the one a
   35+ audience reaches for on a small screen is the phone number, and the one
   that is still one tap away inside the menu is the button. */
@media (max-width: 680px) {
  body.koda-chrome .bar-book{ display: none; }
}
@media (max-width: 560px) {
  /* Below this the number itself goes and the medallion stands alone. It is
     still a tel: link and the whole number is still in its aria-label. */
  body.koda-chrome .bar-phone-txt{ display: none; }
  body.koda-chrome .bar-in{ gap: 8px; }
}

/* Mobile sheet, dropped from the bar. */
/* ═══ ONE STRAY BRACE COST THE PAGE 386 PIXELS (fixed 2026-09-14) ═══════════
   Jeremy: *"somehow I now have a ton of deadspace at the top"* — and it was
   real, on every screen, at every width.

   There used to be a second closing brace on the line above this comment: the
   `@media (max-width: 560px)` block closed itself and then closed again. At
   the top level of a stylesheet a stray closing brace is a parse error, and
   the CSS error-recovery rule is to discard the construct that FOLLOWS it —
   which was the `.bar-sheet` rule below, the one carrying `position: fixed`.

   So the closed mobile menu lost its `position: fixed` and stood up in normal
   flow: six rows at 57px each, 386px of navy-on-navy nothing between the bar
   and <main>, pushing the hero photograph down the page. Every other
   `.bar-sheet` rule parsed fine, which is why it looked like a layout bug
   rather than a syntax one — the sheet was styled, just not taken out of flow.

   IF THIS BREAKS AGAIN, COUNT THE BRACES FIRST — strip the comments, then
   count openers against closers; they must match. Here they did not: 745
   against 746, and the 746th was this one. */
/* A CLOSED SHEET MUST DRAW NOTHING.
   This element is always in the page and collapses to 0fr rather than
   display:none, so it can animate. Its rule and its shadow were on the OUTER
   box, and a border on a zero-height box still paints: a 2px gold line, full
   width, fixed at 76px, on every screen at every width. While the bar was 76px
   tall it hid exactly under the bar's own foil hairline. The moment the bar
   shrank to 64px on scroll it stood clear of it — Jeremy: "the bar at the top
   shrinks as I scroll and leaves behind a horizontal line". So the rule and the
   shadow belong to the OPEN state, and the closed sheet is genuinely nothing. */
body.koda-chrome .bar-sheet{
  position: fixed; top: var(--bar-h); left: 0; right: 0; z-index: 890;
  background: var(--ink-deep);
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .34s var(--ease), top .3s var(--ease);
}
body.koda-chrome .bar-sheet > div{ overflow: hidden; }
body.koda-chrome .bar-sheet.open{
  grid-template-rows: 1fr;
  border-bottom: 2px solid var(--gold-deep);
  box-shadow: 0 24px 48px -18px rgba(0,0,0,.6);
}
/* Both of these hang FROM the bar, so they follow it down when it shrinks —
   otherwise an open menu floats twelve pixels clear of the chrome it dropped
   out of. Sibling selectors: .bar is the <header> and both sit after it. */
body.koda-chrome .bar-sheet a, body.koda-chrome .bar-sheet button{
  display: block; width: 100%; text-align: left; background: none; border: 0;
  color: rgba(255,255,255,.92); font-size: 18px; font-weight: 500; cursor: pointer;
  padding: 16px 22px; border-bottom: 1px solid rgba(255,255,255,.09);
}
body.koda-chrome .bar-sheet a:last-child, body.koda-chrome .bar-sheet button:last-child{ border-bottom: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   SIGN-IN DRAWER — Jeremy: "Have the login be a drawer that comes down rather
   than a login page." It descends from under the bar, over a scrim, and holds
   two doors: a customer looking for their own appointments, and staff.
   ═══════════════════════════════════════════════════════════════════════════ */
body.koda-chrome .scrim{
  position: fixed; inset: 0; z-index: 880; background: rgba(35,15,12,.5);
  backdrop-filter: blur(3px); opacity: 0; visibility: hidden; transition: opacity .3s, visibility .3s;
}
body.koda-chrome .scrim.on{ opacity: 1; visibility: visible; }

body.koda-chrome .drawer{
  position: fixed; top: var(--bar-h); left: 0; right: 0; z-index: 885;
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .42s var(--ease), top .3s var(--ease);
}
body.koda-chrome .drawer.open{ grid-template-rows: 1fr; }
body.koda-chrome .drawer-clip{ overflow: hidden; }
body.koda-chrome .drawer-card{
  width: min(560px, 100% - 28px); margin: 0 auto;
  background: var(--paper);
  border: 1px solid var(--rule); border-top: 0;
  border-radius: 0 0 var(--radius) var(--radius);
  box-shadow: var(--lift-4);
  /* 44px of top padding, not 30: the close button is pinned into that band and
     the segmented control has to clear it. See THE WAY OUT below. */
  padding: 44px 32px 32px;
  position: relative;
}
@media (max-width: 560px) { body.koda-chrome .drawer-card{ padding: 40px 20px 26px; } }

/* ── THE WAY OUT (2026-09-16) ──────────────────────────────────────────────
   Jeremy: *"When clicking sign-in, there isn't a way other than the escape key
   to back out of the sign-in UI (in case of misclicks)."*

   THREE WAYS OUT ALREADY EXISTED AND NONE OF THEM WAS VISIBLE. Escape closes
   it, the scrim closes it, and pressing "Sign in" a second time closes it —
   all three verified working. That is the whole problem: a modal that can only
   be dismissed by things you have to already know about is, to the person who
   mis-clicked, a modal with no way out. A dialog needs a button that says so.

   So there is an X, and it is pinned into the card's own top-right rather than
   floated over the tabs, which is why the card's top padding grew. It is
   injected by koda-chrome.js rather than typed into markup, because this drawer
   is copied verbatim into twenty-three pre-login pages and a close button that
   exists on twenty-two of them is a worse bug than the one it fixes.

   44 x 44: CLAUDE.md's audience skews 35+ and this is the control a shaky tap
   has to hit. The glyph inside it is 16px of stroke; the rest is target. */
body.koda-chrome .drawer-close{
  position: absolute; top: 6px; right: 8px;
  width: 44px; height: 44px; display: grid; place-items: center;
  border: 0; background: none; border-radius: 50%; cursor: pointer;
  color: var(--muted); padding: 0; line-height: 0;
  transition: background .18s, color .18s;
}
body.koda-chrome .drawer-close:hover{ background: var(--page-deep); color: var(--ink); }
body.koda-chrome .drawer-close:focus-visible{
  outline: 2px solid var(--steel-deep); outline-offset: 2px; color: var(--ink);
}

/* ── THE TWO DOORS ─────────────────────────────────────────────────────────
   Jeremy, 2026-09-10: "In the login drawer — darken the toggle between 'I'm a
   customer' and 'KODA staff'."

   The track was --page-deep (#eff3f7) on a white card and the unselected label
   was --muted: a pale grey word on a near-white trough, inside a panel that is
   also white. Nothing said "this is a switch, and you are on the left of it" —
   the selected tab was white-on-almost-white and read as flat text.

   So the TROUGH goes navy and the SELECTED tab stays white. That inverts the
   contrast rather than adding to it: the white pill now sits on something dark,
   which is what makes a segmented control legible at a glance from six feet
   away. The unselected label is white at 82% — a real label on a real ground,
   not grey on grey — and the selected one is full ink on white.

   §4.1: 16px on both, unchanged. This is contrast, not size. */
body.koda-chrome .drawer-tabs{
  display: grid; grid-template-columns: 1fr 1fr; gap: 5px;
  background: linear-gradient(180deg, var(--ink-mid), var(--ink));
  border-radius: 11px; padding: 5px;
  box-shadow: inset 0 2px 6px rgba(0,0,0,.45), inset 0 -1px 0 rgba(255,255,255,.10),
              0 1px 0 rgba(255,255,255,.7);
  margin-bottom: 24px;
}
body.koda-chrome .drawer-tab{
  border: 0; background: none; cursor: pointer; border-radius: 8px;
  padding: 11px 10px; font-size: 16px; font-weight: 600;
  color: rgba(255,255,255,.82);
  transition: background .2s, color .2s, box-shadow .2s;
}
body.koda-chrome .drawer-tab:hover[aria-selected="false"]{
  background: rgba(255,255,255,.10); color: #fff;
}
body.koda-chrome .drawer-tab[aria-selected="true"]{
  background: linear-gradient(180deg, #fff, var(--page-deep));
  color: var(--ink);
  box-shadow: 0 1px 2px rgba(0,0,0,.35), 0 4px 10px -4px rgba(0,0,0,.5),
              inset 0 1px 0 #fff;
}
body.koda-chrome .drawer-pane[hidden]{ display: none; }
body.koda-chrome .drawer h2{ font-size: 26px; margin-bottom: 6px; }
body.koda-chrome .drawer p.sub{ font-size: 16px; color: var(--muted); margin-bottom: 20px; }
body.koda-chrome .drawer-foot{ font-size: 15px; color: var(--muted); margin-top: 18px; text-align: center; }
body.koda-chrome .drawer-foot a{ color: var(--steel-deep); font-weight: 600; text-decoration: underline; }

/* ── Fields ─────────────────────────────────────────────────────────────────
   Jeremy: "input fields be white background to ensure they can be seen with old
   eyes." So every field on this page is #fff on a cream ground, ringed in
   burgundy, and pressed INTO the paper — the inset shadow is what makes a white
   box on a white card still read as somewhere to type. 17px text, 52px tall. */
body.koda-chrome .field{ display: block; margin-bottom: 16px; }
body.koda-chrome .field > span{
  display: block; font-size: 15px; font-weight: 600; color: var(--ink);
  margin-bottom: 7px; letter-spacing: .01em;
}
body.koda-chrome .field input, body.koda-chrome .field select, body.koda-chrome .field textarea{
  width: 100%; background: var(--paper); color: var(--text);
  font-size: 17px; padding: 14px 16px; min-height: 52px;
  border: 1.5px solid var(--rule-firm); border-radius: var(--radius-sm);
  box-shadow: var(--press);
  transition: border-color .18s, box-shadow .18s;
}
body.koda-chrome .field textarea{ min-height: 86px; resize: vertical; line-height: 1.5; }
body.koda-chrome .field input::placeholder, body.koda-chrome .field textarea::placeholder{ color: rgba(30,37,48,.42); }
body.koda-chrome .field input:focus, body.koda-chrome .field select:focus, body.koda-chrome .field textarea:focus{
  outline: 0; border-color: var(--steel);
  box-shadow: var(--press), 0 0 0 4px rgba(63,110,160,.2);
}
body.koda-chrome .field input:invalid:not(:placeholder-shown){ border-color: #c8382c; }
body.koda-chrome .row2{ display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

/* ── THE ADDRESS LOOKUP ─────────────────────────────────────────────────────
   Suggestions under Street Address, from the same Google proxy the office's
   booking screen uses (lib/places.js, through a public door on
   public-booking.js). It is a CONVENIENCE and never a gate: the field is an
   ordinary text input, nothing validates against Google, and when the lookup is
   unavailable it simply never opens — which is why there is no error state
   here to style. */
body.koda-chrome .addr-field{ position: relative; }
body.koda-chrome .addr-field > label{ display: block; }
body.koda-chrome .addr-field > label > span{
  display: block; font-size: 14px; font-weight: 600; letter-spacing: .01em;
  color: var(--text); margin-bottom: 6px;
}
body.koda-chrome .addr-hits{
  position: absolute; z-index: 20; left: 0; right: 0; top: 100%;
  margin-top: -10px;                 /* the field's own bottom margin */
  background: var(--paper);
  border: 1.5px solid var(--steel); border-radius: var(--radius-sm);
  box-shadow: var(--lift-3, 0 18px 40px -14px rgba(13,26,43,.45));
  overflow: hidden;
}
body.koda-chrome .addr-hit{
  display: block; width: 100%; text-align: left; cursor: pointer;
  padding: 11px 12px; min-height: 44px;
  background: none; border: 0; border-bottom: 1px solid var(--rule-soft);
  font-size: 15px; line-height: 1.35; color: var(--text);
}
body.koda-chrome .addr-hit:last-child{ border-bottom: 0; }
body.koda-chrome .addr-hit:hover,
body.koda-chrome .addr-hit:focus-visible{
  background: var(--steel-soft); color: var(--ink); outline: 0;
}
@media (max-width: 520px) { body.koda-chrome .row2{ grid-template-columns: 1fr; gap: 0; } }

/* Honeypot. Off-screen rather than display:none — some bots skip hidden fields
   but happily fill a positioned one, which is the point. */
body.koda-chrome .hp{ position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ── Buttons ────────────────────────────────────────────────────────────── */
body.koda-chrome .btn{
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  font-family: var(--font-body); font-size: 17px; font-weight: 600;
  padding: 16px 30px; border-radius: 11px; border: 0; cursor: pointer;
  transition: transform .15s var(--ease), box-shadow .15s var(--ease), background .2s;
  text-align: center;
}
/* BURGUNDY, AND ONLY HERE. Nocturne's one rule about this colour: it is the
   ACTION colour — what a customer clicks — and it is nothing else on the page.
   No heading, no rule, no band. The gradient and the lift are what this file
   adds on top; the colour itself comes from the theme. */
body.koda-chrome .btn-primary{
  color: #fff;
  background: linear-gradient(180deg, var(--act-hi) 0%, var(--act) 58%, var(--act) 100%);
  box-shadow: 0 2px 3px rgba(16,24,36,.22), 0 12px 24px -10px rgba(77,33,28,.55),
              inset 0 1px 0 rgba(255,255,255,.20);
}
body.koda-chrome .btn-primary:hover:not(:disabled){
  transform: translateY(-2px);
  background: linear-gradient(180deg, var(--act-hi) 0%, var(--act-hi) 100%);
  box-shadow: 0 3px 5px rgba(16,24,36,.24), 0 20px 34px -12px rgba(77,33,28,.6),
              inset 0 1px 0 rgba(255,255,255,.26);
}
body.koda-chrome .btn-primary:active:not(:disabled){ transform: translateY(1px); box-shadow: var(--press); }
body.koda-chrome .btn-primary:disabled{ opacity: .55; cursor: not-allowed; }

body.koda-chrome .btn-ghost{
  color: var(--ink); background: var(--paper);
  border: 1.5px solid var(--rule-firm);
  box-shadow: var(--lift-1), inset 0 1px 0 #fff;
}
body.koda-chrome .btn-ghost:hover{ transform: translateY(-1px); box-shadow: var(--lift-2); border-color: var(--ink); }
body.koda-chrome .btn-ghost:active{ transform: translateY(1px); box-shadow: var(--press); }
body.koda-chrome .btn-wide{ width: 100%; }
body.koda-chrome .btn-sm{ padding: 12px 20px; font-size: 16px; }

/* NO TOP PADDING, AND NO TOP EDGE. Every pre-login page now ends on a LIGHT
   section — an FAQ on the service pages, and since 2026-09-16 the home page's
   closing call as well — so the change of value where this navy starts IS the
   edge, and a border drawn on top of it would be a second one. The gap and the
   only visible line both live on .foot-grid, inside the content width.

   (Until 2026-09-16 the home page was the exception: its closing band fell to
   this exact navy so the two read as one field. That is why Jeremy could not
   tell where the page stopped and the footer began — see A LIGHT GROUND, AND
   THE EDGE IS THE VALUE in home.css.) */
body.koda-chrome .foot{ background: var(--ink); color: rgba(255,255,255,.66); padding: 0 0 26px; font-size: 16px; position: relative; }
body.koda-chrome .foot::before{ content: ''; position: absolute; inset: 0; background-image: var(--grain); opacity: .07; mix-blend-mode: overlay; pointer-events: none; }
body.koda-chrome .foot > *{ position: relative; }
body.koda-chrome .foot-grid{
  display: grid; grid-template-columns: 1.5fr 1fr 1fr 1.3fr; gap: 40px;
  /* The one line between the call and the directory. Gilt, inside the wrap,
     at the same weight as .foot-bottom's rule — a division within a
     section, not a border between two. */
  padding-top: 46px; border-top: 1px solid rgba(201,164,76,.22);
}
@media (max-width: 860px) { body.koda-chrome .foot-grid{ grid-template-columns: 1fr 1fr; gap: 32px; } }
@media (max-width: 520px) { body.koda-chrome .foot-grid{ grid-template-columns: 1fr; } }
body.koda-chrome .foot h3{ font-size: 17px; color: #fff; margin-bottom: 16px; letter-spacing: .02em; }
body.koda-chrome .foot ul{ list-style: none; display: grid; gap: 9px; }
body.koda-chrome .foot a{ color: rgba(255,255,255,.68); font-size: 16px; }
body.koda-chrome .foot a:hover{ color: var(--gold-lit); }
/* ═══ THE FOOTER MARK IS THE BAR'S PLATE (2026-09-14) ══════════════════════
   Jeremy: *"On the pre-login pages: scrap the white outline logo at the bottom
   of the page and replace it with the logo with the white backdrop/gold outline
   that is in the top bar."*

   THE REVERSE IS GONE. `filter: url(#koda-reverse)` flattened the mark to one
   ink — every curve of the file's own artwork, but with the burgundy rule, the
   slate letters and the mascot's whole palette collapsed into cream. It was the
   right answer while the footer had no ground to put light on; it is the wrong
   answer now that the bar has one, because it makes the two ends of the page
   two different marks.

   SO THE FOOT WEARS THE SAME STRUCK PLATE — the rim, the face, the two
   hairlines and the mark in full colour, all of it inherited from the selectors
   above rather than copied down here. That is the point of the shared selector
   list: the plate's foil ramp, its chamfer arithmetic and its two responsive
   step-downs exist exactly once, so the next change to it lands at both ends of
   the page at the same moment.

   Only three things are the footer's own: it is a <span>, so it needs a flex
   display of its own to centre the mark the way the bar's <a> already does; it
   keeps the 18px of air under it that the paragraph below expects; and it does
   NOT take the bar's hover lift, because nothing here is a link.

   `#koda-reverse` is still declared in every page's <svg> defs. Left there
   deliberately — it is inert unless something references it, and it is the one
   piece of this that would be tedious to reconstruct if a dark surface ever
   needs the mark again. */
body.koda-chrome .foot-logo{
  /* THE ONE DECLARATION THAT CANNOT BE SHARED. The bar's logo is an <a> that is
     already a flex ITEM of the rail, so `display: flex` shrink-wraps it there.
     This is a <span> in an ordinary block, where `flex` would make it a
     block-level box and stretch the plate across the whole footer column.
     `inline-flex` is the same box, sized to its contents. */
  display: inline-flex;
  margin-bottom: 18px;
}
body.koda-chrome .foot-line{ display: flex; gap: 11px; align-items: flex-start; margin-bottom: 12px; font-size: 16px; }
body.koda-chrome .foot-line svg{ flex-shrink: 0; margin-top: 4px; opacity: .6; }
body.koda-chrome .foot-line a{ font-family: var(--font-display); font-size: 19px; font-weight: 700; color: #fff; }
body.koda-chrome .foot-line a.plain{ font-family: var(--font-body); font-size: 16px; font-weight: 400; color: rgba(255,255,255,.68); }
body.koda-chrome .foot-line a.plain:hover{ color: var(--gold); }
/* SCOPED TO THE FOOTER, and it has to be: contact.html, about.html and
   holland.html each carry an <address> of their own outside the chrome,
   and a bare `address` rule in this file would restyle all three. */
body.koda-chrome .foot address{ font-style: normal; line-height: 1.6; }
body.koda-chrome .foot-bottom{
  margin-top: 42px; padding-top: 22px; border-top: 1px solid rgba(255,255,255,.12);
  display: flex; flex-wrap: wrap; gap: 14px; justify-content: space-between;
  font-size: 14px; color: rgba(255,255,255,.5);
}
body.koda-chrome .foot-bottom a{ font-size: 14px; }
