.ks-auth-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.ks-auth-header > div:first-child {
  margin: 0 !important;
  min-width: 0;
  gap: 8px !important;
}
.ks-auth-header > [data-ks-variant-switcher] {
  margin: 0 !important;
  padding: 8px 16px !important;
  flex-shrink: 0;
}

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

@media (max-width: 767px) {
  [data-screen-label] .ks-auth-layout {
    display: flex !important;
    flex-direction: column;
    align-items: stretch !important;
  }
  .ks-auth-layout > .ks-auth-scene {
    order: 1;
    width: 100%;
  }
}

:root {
  --ks-accent: #16506b;
  --ks-accent-press: #0e3a50;
  --ks-accent-deep: #123246;
  --ks-accent-tint: #f1f6f9;
  --ks-accent-on-eyebrow: #9cc0d1;
  --ks-accent-on-muted: #c9d4da;
  --ks-market-ink: #1f1b18;
  --ks-market-muted: #635a52;
  --ks-market-faint: #8a8079;
  --ks-market-paper: #fff;
  /* The footer band is dark chrome in *both* themes. It was painted with
     --ks-market-ink, which is a text colour: correct at #1f1b18 by day, and at night it
     flipped to #f5f0e6 and put a cream slab under white text at 1.14:1. A surface gets a
     surface token. The light value is identical to the ink it replaces, so daytime is
     unchanged. */
  --ks-market-chrome: #1f1b18;
  --ks-market-cream: #f7f4ea;
  --ks-market-field: #f3f1e7;
  --ks-market-line: #efeae3;
  --ks-market-line-strong: #e1dace;
  --ks-market-line-soft: #e7e2d4;
  --ks-market-line-faint: #dfd8cf;
  --ks-market-ink-strong: #3b342e;
  --ks-market-ink-body: #4a423c;
  --ks-market-ink-soft: #5a5245;
  --ks-market-ink-dim: #cfc6bc;
  --ks-market-faint-warm: #a79e93;
  --ks-market-sunk: #f2eee6;
  --ks-market-warm: #f1eee2;
  --ks-market-bright: #fcfbf7;
  --ks-market-veil: #e4dfd2;
  --ks-market-positive: #2f7a3f;
  --ks-market-warning: #a4462b;
  --ks-market-warning-line: #e7cfc7;
  --ks-accent-ink: var(--ks-accent);
  --ks-market-shadow: 0 10px 28px rgba(22, 48, 64, 0.12);
  --ks-accent-green: var(--ks-accent);
  color-scheme: light;
}

:root[data-ks-accent="red"] {
  --ks-accent: #9b3f43;
  --ks-accent-press: #743034;
  --ks-accent-deep: #4f2428;
  --ks-accent-tint: #fbf2f2;
  --ks-accent-on-eyebrow: #e3d2d2;
  --ks-accent-on-muted: #f3f0f0;
}

:root[data-ks-accent="green"] {
  --ks-accent: #356b50;
  --ks-accent-press: #28523d;
  --ks-accent-deep: #1d392c;
  --ks-accent-tint: #f0f7f3;
  --ks-accent-on-eyebrow: #d0dfd7;
  --ks-accent-on-muted: #f6f7f6;
}

:root[data-ks-accent="orange"] {
  --ks-accent: #a9551f;
  --ks-accent-press: #814016;
  --ks-accent-deep: #572d13;
  --ks-accent-tint: #fcf4ed;
  --ks-accent-on-eyebrow: #f4ede7;
  --ks-accent-on-muted: #ffffff;
}

/* Dark mode for the marketplace screens.
   The 13 August export replaced almost every route with documents that hardcode their
   neutrals, so the Appearance card's Dark option repainted the tab bar and nothing else. The
   build now substitutes those literals for the roles below; this is what the roles become at
   night. Every pair is checked at 4.5:1 in accent-contrast.test.mjs. */
:root[data-ks-theme="dark"] {
  --ks-market-ink: #f5f0e6;
  --ks-market-ink-strong: #ece5d8;
  --ks-market-ink-body: #ded6c8;
  --ks-market-ink-soft: #cdc4b6;
  --ks-market-muted: #b7ada0;
  --ks-market-faint: #a79e90;
  --ks-market-ink-dim: #9a9186;
  --ks-market-faint-warm: #a79e90;
  --ks-market-paper: #2c2823;
  --ks-market-chrome: #1a1713;
  --ks-market-cream: #262219;
  --ks-market-field: #211e19;
  --ks-market-sunk: #211e19;
  --ks-market-warm: #2a251e;
  --ks-market-bright: #322d26;
  --ks-market-veil: #322d26;
  --ks-market-line: #3d372f;
  --ks-market-line-strong: #4c453b;
  --ks-market-line-soft: #453e35;
  --ks-market-line-faint: #423b33;
  --ks-market-positive: #7fc08f;
  --ks-market-warning: #eba894;
  --ks-market-warning-line: #5c3b32;
  --ks-market-shadow: 0 10px 28px rgba(0, 0, 0, 0.44);
  --ks-accent-ink: color-mix(in srgb, var(--ks-accent) 42%, #fff);
  --ks-accent-tint: color-mix(in srgb, var(--ks-accent) 22%, #211e19);
  color-scheme: dark;
}

@media (prefers-color-scheme: dark) {
  :root[data-ks-theme="system"] {
    --ks-market-ink: #f5f0e6;
    --ks-market-ink-strong: #ece5d8;
    --ks-market-ink-body: #ded6c8;
    --ks-market-ink-soft: #cdc4b6;
    --ks-market-muted: #b7ada0;
    --ks-market-faint: #a79e90;
    --ks-market-ink-dim: #9a9186;
    --ks-market-faint-warm: #a79e90;
  --ks-market-faint-warm: #a79e90;
    --ks-market-paper: #2c2823;
    --ks-market-chrome: #1a1713;
    --ks-market-cream: #262219;
    --ks-market-field: #211e19;
    --ks-market-sunk: #211e19;
    --ks-market-warm: #2a251e;
    --ks-market-bright: #322d26;
    --ks-market-veil: #322d26;
    --ks-market-line: #3d372f;
    --ks-market-line-strong: #4c453b;
    --ks-market-line-soft: #453e35;
    --ks-market-line-faint: #423b33;
    --ks-market-positive: #7fc08f;
    --ks-market-warning: #eba894;
    --ks-market-warning-line: #5c3b32;
    --ks-market-shadow: 0 10px 28px rgba(0, 0, 0, 0.44);
    --ks-accent-ink: color-mix(in srgb, var(--ks-accent) 42%, #fff);
    --ks-accent-tint: color-mix(in srgb, var(--ks-accent) 22%, #211e19);
    color-scheme: dark;
  }
}

html,
body {
  background: var(--ks-market-paper) !important;
}

body {
  color: var(--ks-market-ink);
  font-family: Cabin, Verdana, sans-serif;
}

/* The 2026 rebuild is fluid. This deliberately retires the handoff's phone canvas. */
#bp-mobile [data-screen-label],
#bp-pc [data-screen-label] {
  background: var(--ks-market-paper) !important;
  box-shadow: none !important;
  color: var(--ks-market-ink) !important;
  height: auto !important;
  min-height: 100dvh;
  max-width: 1200px !important;
  overflow-x: clip !important;
}

@media (max-width: 767.98px) {
  #bp-mobile [data-screen-label] {
    min-width: 0 !important;
    width: 100% !important;
  }
}

/* Retire physical-board ornament while retaining the current DOM and live wiring. */
[style*="cork-board"],
[style*="cork-tile"] {
  background-color: var(--ks-market-cream) !important;
  background-image: none !important;
}

[data-screen-label] [style*="rotate("],
[data-screen-label] [style*="rotateZ("] {
  rotate: 0deg !important;
  transform: none !important;
}

[data-screen-label] a,
[data-screen-label] button {
  transition: background-color 150ms ease, border-color 150ms ease, box-shadow 150ms ease,
    color 150ms ease;
}

[data-screen-label] a:focus-visible,
[data-screen-label] button:focus-visible,
[data-screen-label] input:focus-visible,
[data-screen-label] select:focus-visible,
.ks-accent-choice:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--ks-accent) 40%, white);
  outline-offset: 3px;
}

/* Translate the old action role into the user-selected accent. */
[data-screen-label] [style*="#3F6F63"],
[data-screen-label] [style*="#3f6f63"] {
  --ks-accent-green: var(--ks-accent) !important;
}

[data-screen-label] input,
[data-screen-label] textarea,
[data-screen-label] select {
  border-radius: 13px !important;
}

.ks-accent-preference {
  background: var(--ks-market-paper);
  border: 1px solid var(--ks-market-line);
  border-radius: 20px;
  color: var(--ks-market-ink);
  font-family: Cabin, Verdana, sans-serif;
  margin: clamp(16px, 3vw, 28px);
  padding: clamp(16px, 3vw, 22px);
}

.ks-accent-preference h2 {
  font: 800 clamp(20px, 2.7vw, 27px)/1.1 "Bricolage Grotesque", sans-serif;
  letter-spacing: -0.02em;
  margin: 0 0 6px;
}

.ks-accent-preference p {
  color: var(--ks-market-muted);
  font: 400 14px/1.5 Literata, Georgia, serif;
  margin: 0 0 14px;
  max-width: 68ch;
}

.ks-accent-options {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(4, minmax(64px, 1fr));
}

.ks-accent-choice {
  align-items: center;
  /* Was #fff while the label used --ks-market-ink. At night the ink went cream and the chip
     stayed white: Red, Green and Orange sat at 1.14:1 and vanished, while the selected one
     looked fine because it takes --ks-accent-tint instead. Light mode is unchanged —
     --ks-market-paper is #fff by day. */
  background: var(--ks-market-paper);
  border: 1px solid var(--ks-market-line-strong);
  border-radius: 14px;
  color: var(--ks-market-ink);
  cursor: pointer;
  display: flex;
  font: 700 14px/1 Cabin, sans-serif;
  gap: 8px;
  justify-content: center;
  min-height: 48px;
  padding: 10px;
}

.ks-accent-choice[aria-pressed="true"] {
  background: var(--ks-accent-tint);
  border-color: var(--ks-accent);
  box-shadow: inset 0 0 0 1px var(--ks-accent);
}

.ks-accent-swatch {
  background: var(--swatch);
  /* The ring separates the swatch from the chip it sits on, so it follows the chip. */
  border: 2px solid var(--ks-market-paper);
  border-radius: 50%;
  box-shadow: 0 0 0 1px var(--ks-market-line-strong);
  height: 18px;
  width: 18px;
}

@media (max-width: 460px) {
  .ks-accent-options { grid-template-columns: repeat(2, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  [data-screen-label] *,
  .ks-accent-choice { transition-duration: 0.01ms !important; }
}

/* Persistent mobile bottom bar.
   The marketplace export documents carry no bottom navigation of their own, so the build
   emits one per page (see tabBar in tools/build.mjs). It is fixed to the viewport rather
   than sticky inside the screen, because the exported screens scroll as one document and a
   sticky bar would sit at the foot of a very long page instead of on the glass. */
.ks-tabbar {
  /* The selected destination is drawn in the accent. At night the accent is a deep blue on a
     near-black bar — 1.6:1 — so the role is themed rather than the value: dark surfaces get a
     lightened mix of whichever accent the resident chose. */
  --ks-tabbar-active: var(--ks-accent);
  display: none;
}

:root[data-ks-theme="dark"] .ks-tabbar {
  --ks-tabbar-active: color-mix(in srgb, var(--ks-accent) 42%, #fff);
}

@media (prefers-color-scheme: dark) {
  :root[data-ks-theme="system"] .ks-tabbar {
    --ks-tabbar-active: color-mix(in srgb, var(--ks-accent) 42%, #fff);
  }
}

@media (max-width: 767.98px) {
  .ks-tabbar {
    align-items: stretch;
    background: var(--ks-paper, #fffdf7);
    border-top: 1px solid rgba(var(--ks-rule-rgb, 33, 30, 25), 0.18);
    bottom: 0;
    box-shadow: 0 -6px 16px rgba(40, 24, 8, 0.16);
    display: flex;
    gap: 2px;
    left: 0;
    padding: 8px 6px calc(10px + env(safe-area-inset-bottom));
    position: fixed;
    right: 0;
    z-index: 950;
  }

  .ks-tabbar__item {
    align-items: center;
    color: var(--ks-muted, #5a5245);
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    gap: 5px;
    min-height: 56px;
    text-decoration: none;
  }

  .ks-tabbar__icon {
    align-items: center;
    display: flex;
    height: 34px;
    justify-content: center;
  }

  .ks-tabbar__label {
    font: 400 10.5px/1.2 Cabin, Verdana, sans-serif;
  }

  .ks-tabbar__item[aria-current="page"] {
    color: var(--ks-tabbar-active);
  }

  .ks-tabbar__item[aria-current="page"] .ks-tabbar__label {
    font-weight: 700;
  }

  /* The centre destination is the site's one primary action, drawn as a filled key the
     way the original handoff drew it. */
  .ks-tabbar__item:nth-child(3) .ks-tabbar__icon {
    background: var(--ks-accent);
    border-radius: 14px;
    color: #fff;
    width: 52px;
  }

  .ks-tabbar__item:nth-child(3) .ks-tabbar__label {
    color: var(--ks-ink, #211e19);
    font-weight: 700;
  }

  /* Keep the bar off the last row of content on every screen it overlays. */
  #bp-mobile [data-screen-label] {
    padding-bottom: calc(78px + env(safe-area-inset-bottom));
  }
}

/* ---------------------------------------------------------------------------
   The camera check-in sheet, the resident's own code, and the two launchers.

   Drawn here rather than into the handoff's Kaki Check-in screen. That screen is an
   extracted document with duplicate ids across its two breakpoints, and adding a camera
   into it would mean editing generated markup that the next export overwrites. An overlay
   owns its own surface, survives a re-export untouched, and is one element to remove if the
   journey changes again.

   Colours are roles, not values: the sheet sits on --ks-paper so it inverts with everything
   else, and the viewfinder stays black in both themes because it is a camera, not a surface.
   --------------------------------------------------------------------------- */
.ks-scan {
  align-items: flex-end;
  background: rgba(20, 16, 10, 0.62);
  bottom: 0;
  display: flex;
  justify-content: center;
  left: 0;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 1200;
}

.ks-scan__sheet {
  background: var(--ks-paper, #fffdf7);
  border-radius: 20px 20px 0 0;
  box-shadow: 0 -10px 30px rgba(20, 16, 10, 0.32);
  color: var(--ks-ink, #211e19);
  max-height: 92vh;
  max-width: 460px;
  overflow-y: auto;
  padding: 16px 18px calc(20px + env(safe-area-inset-bottom));
  width: 100%;
}

@media (min-width: 768px) {
  .ks-scan {
    align-items: center;
  }

  .ks-scan__sheet {
    border-radius: 20px;
  }
}

/* The partner's check-in figures.
   -------------------------------
   A dashboard panel, not a marketing card: the numbers are the point, so they are the largest
   thing in it, and the thirty-day strip is a shape rather than a chart with furniture. */
.ks-stats {
  background: var(--ks-paper, #fffdf7);
  border: 1px solid rgba(var(--ks-rule-rgb, 33, 30, 25), 0.16);
  border-radius: 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin: 0 auto 18px;
  max-width: 1120px;
  padding: 20px;
}

.ks-stats__title {
  font: 700 17px/1.25 "Bricolage Grotesque", Verdana, sans-serif;
  margin: 0;
}

.ks-stats__figures {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
}

.ks-stats__figure {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ks-stats__value {
  font: 800 28px/1 "Bricolage Grotesque", Verdana, sans-serif;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

.ks-stats__label {
  color: var(--ks-muted, #5a5245);
  font: 400 13px/1.4 Cabin, Verdana, sans-serif;
}

.ks-stats__chart {
  align-items: flex-end;
  background: var(--ks-sunk, #f3f1e7);
  border-radius: 10px;
  display: flex;
  gap: 2px;
  height: 64px;
  padding: 8px;
}

.ks-stats__bar {
  background: var(--ks-accent);
  border-radius: 2px;
  flex: 1 1 0;
  min-height: 2px;
}

.ks-stats__note {
  color: var(--ks-muted, #5a5245);
  font: 400 13px/1.5 Literata, Georgia, serif;
  margin: 0;
}

/* Where a signed-out reader's deals would have been.
   ---------------------------------------------------
   Shaped like the deal cards it replaces so the section keeps its rhythm, but plainly a door
   rather than an offer: one accent rule, no price badge, and the whole card is the control. */
.ks-locked {
  background: var(--ks-paper, #fffdf7);
  border: 1px solid var(--ks-accent);
  border-radius: 16px;
  color: var(--ks-ink, #211e19);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 18px;
  text-align: left;
  width: 100%;
}

.ks-locked:focus-visible {
  outline: 3px solid var(--ks-accent);
  outline-offset: 2px;
}

.ks-locked__label {
  font: 700 16px/1.3 "Bricolage Grotesque", Verdana, sans-serif;
}

.ks-locked__line {
  color: var(--ks-muted, #5a5245);
  font: 400 14.5px/1.55 Literata, Georgia, serif;
}

.ks-locked__cta {
  color: var(--ks-accent);
  font: 700 14px/1 Cabin, Verdana, sans-serif;
  margin-top: 4px;
}

/* The scanner is the screen, not a card on it.
   ------------------------------------------------
   A viewfinder inside a bottom sheet gave the camera about a third of the glass, and a QR
   code on a shop counter had to be framed inside that. Full-bleed is not decoration here: it
   is the difference between a code that reads at arm's length and one that does not. The
   sheet layout is kept for every other use of this overlay — "My code" is still a sheet. */
.ks-scan--full {
  align-items: stretch;
  background: #0d0b08;
}

.ks-scan--full .ks-scan__sheet {
  background: #0d0b08;
  border-radius: 0;
  box-shadow: none;
  color: #fff;
  display: flex;
  flex-direction: column;
  height: 100dvh;
  max-height: none;
  max-width: none;
  overflow: hidden;
  padding: 0;
  position: relative;
}

/* The head floats over the camera rather than sitting above it: any strip of chrome that
   takes its own height is height the viewfinder does not get. */
.ks-scan--full .ks-scan__head {
  left: 0;
  padding: calc(10px + env(safe-area-inset-top)) 12px 10px;
  position: absolute;
  right: 0;
  top: 0;
  z-index: 2;
}

.ks-scan--full .ks-scan__title {
  color: #fff;
  font-size: 17px;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.55);
}

/* Full screen, the top right corner belongs to "My code" — it is the one other thing this
   screen does, and the owner asked for it there by name. Closing moves to the left. */
.ks-scan--full .ks-scan__close {
  background: rgba(13, 11, 8, 0.55);
  color: #fff;
  order: -1;
}

.ks-scan--full .ks-scan__tools {
  margin-left: auto;
}

.ks-scan--full .ks-scan__body {
  flex: 1 1 auto;
  margin: 0;
  min-height: 0;
  overflow-y: auto;
}

.ks-scan--full .ks-scan__stage {
  aspect-ratio: auto;
  border-radius: 0;
  height: 100%;
}

.ks-scan--full .ks-scan__status {
  background: linear-gradient(rgba(13, 11, 8, 0), rgba(13, 11, 8, 0.72) 38%);
  color: #fff;
  margin: 0;
  padding: 26px 18px calc(18px + env(safe-area-inset-bottom));
  position: relative;
  text-align: center;
  z-index: 2;
}

.ks-scan--full .ks-scan__status[data-tone="error"] {
  color: #ffc9bb;
}

.ks-scan--full .ks-scan__status[data-tone="ok"] {
  color: #b9e6d8;
}

/* The result of a scan replaces the camera, and then this is an ordinary reading surface
   again — white text on a black stage is right for a viewfinder and wrong for a paragraph. */
.ks-scan--full[data-ks-stage="result"],
.ks-scan--full[data-ks-stage="result"] .ks-scan__sheet {
  background: var(--ks-paper, #fffdf7);
  color: var(--ks-ink, #211e19);
}

.ks-scan--full[data-ks-stage="result"] .ks-scan__head {
  position: static;
  padding: calc(12px + env(safe-area-inset-top)) 16px 0;
}

.ks-scan--full[data-ks-stage="result"] .ks-scan__title,
.ks-scan--full[data-ks-stage="result"] .ks-scan__close {
  color: var(--ks-ink, #211e19);
  text-shadow: none;
}

.ks-scan--full[data-ks-stage="result"] .ks-scan__close {
  background: none;
}

.ks-scan--full[data-ks-stage="result"] .ks-scan__body {
  padding: 0 16px;
}

.ks-scan--full[data-ks-stage="result"] .ks-scan__status {
  background: none;
  color: inherit;
  padding: 14px 16px calc(18px + env(safe-area-inset-bottom));
  text-align: left;
}

/* "My code" while the camera is open. The page-level button is behind the overlay, so the
   control has to exist inside it or the resident has to close the camera to find it. */
.ks-scan__mine-inline {
  align-items: center;
  background: rgba(255, 253, 247, 0.94);
  border: 0;
  border-radius: 999px;
  color: #211e19;
  cursor: pointer;
  display: flex;
  font: 700 13px/1 Cabin, Verdana, sans-serif;
  gap: 7px;
  padding: 10px 14px;
}

.ks-scan__mine-inline:focus-visible {
  outline: 3px solid #fff;
  outline-offset: 2px;
}

/* The static panel behind the camera. On a phone it is what a refused camera permission
   leaves on the glass; on a desktop it is the whole screen. */
.ks-checkin {
  align-items: center;
  display: flex;
  justify-content: center;
  min-height: 60vh;
  padding: clamp(24px, 6vw, 64px) 20px;
}

.ks-checkin__panel {
  max-width: 460px;
  text-align: center;
}

.ks-checkin__title {
  font: 800 clamp(23px, 3.2vw, 30px)/1.2 "Bricolage Grotesque", Verdana, sans-serif;
  letter-spacing: -0.025em;
  margin: 0 0 10px;
}

.ks-checkin__lede {
  color: var(--ks-muted, #5a5245);
  font: 400 16px/1.6 Literata, Georgia, serif;
  margin: 0;
}

.ks-scan__head {
  align-items: center;
  display: flex;
  gap: 12px;
  justify-content: space-between;
}

.ks-scan__title {
  font: 700 19px/1.25 "Bricolage Grotesque", Verdana, sans-serif;
  margin: 0;
}

.ks-scan__close {
  background: none;
  border: 0;
  border-radius: 999px;
  color: var(--ks-muted, #5a5245);
  cursor: pointer;
  font: 400 26px/1 Cabin, Verdana, sans-serif;
  height: 44px;
  width: 44px;
}

.ks-scan__close:focus-visible,
.ks-scan__action:focus-visible,
.ks-scan-launch:focus-visible,
.ks-scan-mine:focus-visible {
  outline: 3px solid var(--ks-accent);
  outline-offset: 2px;
}

.ks-scan__body {
  margin: 14px 0 0;
}

/* The viewfinder keeps a fixed aspect so the sheet does not jump in height when the camera
   reports its real dimensions a moment after the stream opens. */
.ks-scan__stage {
  aspect-ratio: 1 / 1;
  background: #0d0b08;
  border-radius: 16px;
  overflow: hidden;
  position: relative;
  width: 100%;
}

.ks-scan__stage video {
  display: block;
  height: 100%;
  object-fit: cover;
  width: 100%;
}

.ks-scan__reticle {
  border: 3px solid rgba(255, 255, 255, 0.92);
  border-radius: 14px;
  box-shadow: 0 0 0 100vmax rgba(13, 11, 8, 0.34);
  height: 62%;
  left: 19%;
  position: absolute;
  top: 19%;
  width: 62%;
}

/* The code is a black-on-white matrix in both themes: a scanner reads contrast, and
   inverting it at night is the one place theming would break the feature. */
.ks-scan__code {
  background: #fff;
  border-radius: 12px;
  margin: 0 auto;
  max-width: 280px;
  padding: 14px;
}

.ks-scan__code svg {
  display: block;
  height: auto;
  width: 100%;
}

.ks-scan__status {
  font: 400 14px/1.5 Literata, Georgia, serif;
  margin: 12px 0 0;
}

.ks-scan__status[data-tone="error"] {
  color: var(--ks-accent-rust, #96412f);
}

.ks-scan__status[data-tone="ok"] {
  color: var(--ks-accent-green, #3f6f63);
}

.ks-scan__action {
  background: var(--ks-accent);
  border: 0;
  border-radius: 12px;
  color: #fff;
  cursor: pointer;
  display: block;
  font: 700 15px/1 Cabin, Verdana, sans-serif;
  margin: 12px 0 0;
  padding: 14px 16px;
  text-align: center;
  text-decoration: none;
  width: 100%;
}

.ks-scan__action--quiet {
  background: none;
  border: 1px solid rgba(var(--ks-rule-rgb, 33, 30, 25), 0.28);
  color: var(--ks-ink, #211e19);
}

/* Both launchers exist only on a phone. The desktop journey is the click-through on a
   partner's listing, so there is nothing here to press on a laptop. */
.ks-scan-launch,
.ks-scan-mine {
  display: none;
}

@media (max-width: 767.98px) {
  .ks-scan-launch {
    background: var(--ks-accent);
    border: 0;
    border-radius: 14px;
    bottom: calc(92px + env(safe-area-inset-bottom));
    color: #fff;
    cursor: pointer;
    display: block;
    font: 700 15px/1 Cabin, Verdana, sans-serif;
    left: 16px;
    padding: 15px 16px;
    position: fixed;
    right: 16px;
    z-index: 940;
  }

  .ks-scan-mine {
    align-items: center;
    background: var(--ks-paper, #fffdf7);
    border: 1px solid rgba(var(--ks-rule-rgb, 33, 30, 25), 0.22);
    border-radius: 999px;
    box-shadow: 0 2px 10px rgba(40, 24, 8, 0.14);
    color: var(--ks-ink, #211e19);
    cursor: pointer;
    display: flex;
    font: 700 13px/1 Cabin, Verdana, sans-serif;
    gap: 7px;
    padding: 10px 14px;
    position: fixed;
    right: 12px;
    top: calc(12px + env(safe-area-inset-top));
    z-index: 960;
  }
}

/* ---- The Home hero rail ---------------------------------------------------- */

/*
 * Make `hidden` actually hide a hero slide.
 *
 * The slides carry `display:flex` in the inline style the design export owns, and an inline
 * declaration beats the user agent's `[hidden] { display: none }`. So `hidden` set nothing but an
 * attribute: both slides stayed 440px tall in the same `grid-area:1/1`, and the later one in the
 * DOM painted over the other permanently. The carousel changed its dots and its `aria-pressed`
 * and never once changed its picture - Home showed the What's New banner and only that, from the
 * day the rail shipped.
 *
 * `!important` is not decoration here: an author stylesheet needs it to beat an inline
 * declaration, which is also why this cannot live inline beside everything else. Doing it in CSS
 * rather than by assigning `style.display` in the script keeps `hidden` the single source of
 * truth and hides the second slide before any script runs, so the banner is right even if
 * whats-new.js never loads.
 */
.ks-hero__slide[hidden] { display: none !important; }

/*
 * The slide itself. Once whats-new.js takes over, `hidden` comes off every slide and each one is
 * positioned by `translateX` instead, so the banner leaving and the banner arriving are both on
 * screen for the length of the transition and the rail's `overflow:hidden` is what crops them.
 *
 * `transform` and nothing else: it is compositor-driven, so a 440px photograph slides without
 * relayout or repaint. Animating `left` or `margin` here would lay out the whole hero every frame.
 */
.ks-hero__slide {
  transition: transform 620ms cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: transform;
}

/* Reduced motion keeps the carousel and drops the travel, matching the script, which keeps the
   dots and drops only the automation. The banner still changes; it just does not move to do it. */
@media (prefers-reduced-motion: reduce) {
  .ks-hero__slide {
    transition: none;
  }
}

/*
 * The header search field gets its own row on a phone.
 *
 * The export's header is one flex row: logo block and points button are `flex:none`, the search
 * between them is `flex:1; min-width:0`. That makes the field the remainder of the row, and on a
 * 375px screen the remainder is nothing. Measured on the live apex before this rule: wrapper 34px,
 * input 4px, magnifier 0px, against a 162px logo block and an 83px points button.
 *
 * `order` rather than a DOM move, because the same markup serves both breakpoints and the desktop
 * row is correct as authored. Above 768px none of this applies and the field stays inline.
 *
 * `flex` needs `!important` only because the export writes `flex:1` as an inline style; the rest
 * of the rule does not, and should not acquire it.
 */
@media (max-width: 767.98px) {
  div:has(> .ks-hdr__search) {
    flex-wrap: wrap;
    row-gap: 10px;
  }

  .ks-hdr__search {
    /* Full basis is what forces the wrap; `order` puts it after the button it wrapped past. */
    flex: 1 0 100% !important;
    order: 3;
    /* 40px as authored, and a search field is a primary target on the screen that "serves
       utility". 44px is the floor, not a preference. */
    min-height: 44px;
    box-sizing: border-box;
  }
}
