/* ============================================================================
   Nova Lounge design tokens

   The identity is built around open water, polished metal, and daylight. The
   background carries the colour; interface surfaces stay quiet and translucent.
   Legacy vessel-token names remain as aliases because the booking UI already uses
   them extensively, but their values now resolve to the blue and silver system.
   ========================================================================== */
:root {
  --atlantic: #0754c7;
  --electric-blue: #138bff;
  --sky-blue: #64c8ff;
  --silver: #e3edf5;
  --steel: #afc0d0;
  --ink-navy: #061a3a;

  --ground: var(--atlantic);
  --ground-2: #073f9a;
  --ground-3: #061f54;

  --ink: #f8fbff;
  --ink-muted: #d7e4ef;
  --ink-faint: #e3edf5;

  /* Compatibility aliases for the original component layer. */
  --cognac: var(--sky-blue);
  --cognac-deep: var(--atlantic);
  --oxblood: #08347a;
  --cream: var(--silver);
  --hull: #0f72dc;

  --success: #42d39a;
  --danger: #ff7d7d;

  --surface: rgba(5, 31, 79, 0.66);
  --surface-strong: rgba(4, 24, 64, 0.84);
  --surface-soft: rgba(227, 237, 245, 0.12);
  --line: rgba(227, 237, 245, 0.24);
  --line-strong: rgba(227, 237, 245, 0.44);
  --shadow: 0 24px 64px rgba(4, 26, 69, 0.22);

  /* Tight radii read as considered; 8px on everything reads as a default. */
  --radius: 3px;
  --radius-lg: 6px;

  --font-display: "Instrument Sans", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Instrument Sans", "Helvetica Neue", Arial, sans-serif;
  --font-utility: var(--font-body);

  /* Fixed type steps prevent viewport-width scaling from making text unpredictable. */
  --text-12: 0.75rem;
  --text-14: 0.875rem;
  --text-16: 1rem;
  --text-18: 1.125rem;
  --text-22: 1.375rem;
  --text-30: 1.875rem;
  --text-44: 3.5rem;
  --text-64: 5rem;

  /* --- Spacing scale ------------------------------------------------------
     ONE scale. Every margin, gap and padding in this file resolves to a step
     below. A value that is not on the scale is a defect - see LAYOUT_RULES.md
     at the repo root, and `measure.mjs --layout` which enforces it.          */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;

  /* Section rhythm */
  --band-y: clamp(72px, 9vw, 132px);
  --gutter: clamp(20px, 4vw, 48px);

  /* THE SPINE. Every section's content resolves to this width, so headings and
     the content they head share a left edge. Four different max-widths (1080 /
     1120 / 1180) put four different left edges on the page. */
  --content-max: 1180px;
  --story-rail: 520px;
  --gallery-max-height: 800px;

  /* Inset for an icon drawn inside a field, measured from the field's border.
     A chevron or a picker glyph hard against the edge is the tell. */
  --field-icon-inset: var(--space-3);
}

* {
  box-sizing: border-box;
  letter-spacing: 0 !important;
}

html {
  scroll-behavior: smooth;
  /* The header is sticky and 72px tall. Without this, every in-page anchor lands
     with its own heading hidden underneath it - "Choose a date" was sitting behind
     the header on a #booking jump. */
  scroll-padding-top: 92px;
}

body {
  min-width: 320px;
  margin: 0;
  color: var(--ink);
  background: var(--atlantic);
  font-family: var(--font-body);
  font-size: var(--text-16);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body.no-webgl {
  background: linear-gradient(135deg, #0643a4 0%, #0c6cdb 36%, #3caaf3 67%, #d7e6f0 100%);
}

button,
input,
select {
  font: inherit;
}

button,
a,
input,
select {
  outline-offset: 3px;
}

button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible {
  outline: 3px solid var(--cognac);
}

img {
  display: block;
  max-width: 100%;
}

#webglBackground,
.ambient-scrim {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
}

#webglBackground {
  z-index: -3;
  pointer-events: none;
  background: var(--ground);
}

/* Warm scrim, not a blue one. This sits between the WebGL cabin and the UI: its
   job is to hold text contrast without draining the warmth out of the render. */
.ambient-scrim {
  z-index: -2;
  pointer-events: none;
  background:
    linear-gradient(90deg, rgba(10, 8, 6, 0.88), rgba(10, 8, 6, 0.42) 46%, rgba(10, 8, 6, 0.80)),
    linear-gradient(180deg, rgba(10, 8, 6, 0.30), rgba(10, 8, 6, 0.88) 76%);
  transition: background 500ms ease;
}

body.particle-background-ready[data-page="home"] .ambient-scrim {
  background:
    linear-gradient(90deg, rgba(10, 8, 6, 0.94) 8%, rgba(10, 8, 6, 0.72) 42%, rgba(10, 8, 6, 0.18) 72%, rgba(10, 8, 6, 0.48)),
    linear-gradient(180deg, rgba(10, 8, 6, 0.18), rgba(10, 8, 6, 0.34) 64%, rgba(10, 8, 6, 0.88));
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  min-height: 72px;
  padding: var(--space-3) var(--gutter);
  background: rgba(10, 8, 6, 0.72);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(20px) saturate(1.2);
}

.brand-mark,
.site-nav a,
.button,
.small-button,
.segment,
.date-tile,
.slot-tile {
  -webkit-tap-highlight-color: transparent;
}

.brand-mark {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  gap: var(--space-4);
  color: var(--ink);
  text-decoration: none;
  font-family: var(--font-display);
  font-size: var(--text-18);
  font-weight: 500;
  letter-spacing: 0.02em;
  font-variation-settings: "SOFT" 0, "WONK" 0, "opsz" 20;
}

/* A filled circle with a letter in it is the default placeholder logo. A hairline
   ring reads as a signet - closer to a members' club than an avatar. */
.brand-symbol {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  color: var(--cream);
  background: transparent;
  border: 1px solid var(--cognac);
  border-radius: 50%;
  font-family: var(--font-display);
  font-size: var(--text-16);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-indent: 0.06em;
}

.brand-mark:hover .brand-symbol {
  border-color: var(--cream);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  overflow-x: auto;
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-width: 54px;
  min-height: 44px;
  padding: 0 var(--space-4);
  color: var(--ink-muted);
  text-decoration: none;
  border-radius: var(--radius);
}

.site-nav a:hover {
  color: var(--ink);
  background: var(--surface-soft);
}

.band {
  position: relative;
  padding: var(--band-y) var(--gutter);
}

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: center;
  min-height: 88svh;
  padding-top: clamp(64px, 10vw, 120px);
  padding-bottom: var(--band-y);
  overflow: hidden;
}

/* On the spine like every other section. The hero used to start at the raw gutter
   (48px) while every section below it started at 130px, so the page had no single
   left edge. The text measure is held by max-width on h1 / .hero-lede instead. */
.hero-copy {
  width: min(var(--content-max), 100%);
  margin-inline: auto;
  padding: 0;
  background: none;
}

.eyebrow {
  margin: 0 0 18px;
  color: var(--cognac);
  font-family: var(--font-utility);
  font-size: var(--text-12);
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

/* A hairline before the eyebrow: cheap to draw, and it reads as typeset rather
   than as text that happens to be small and orange. */
.eyebrow::before {
  content: "";
  display: inline-block;
  width: 28px;
  height: 1px;
  margin-right: 12px;
  vertical-align: 0.3em;
  background: var(--cognac);
}

h1,
h2,
h3,
p {
  overflow-wrap: anywhere;
}

h1,
h2,
h3 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.06;
  letter-spacing: -0.015em;
  /* Fraunces axes: slightly soft terminals, no wonk. Warm without being novelty. */
  font-variation-settings: "SOFT" 24, "WONK" 0, "opsz" 96;
}

h1 {
  max-width: 15ch;
  font-size: var(--text-64);
  letter-spacing: -0.025em;
}

h2 {
  max-width: 20ch;
  font-size: var(--text-44);
}

h3 {
  font-size: var(--text-22);
  line-height: 1.2;
  letter-spacing: -0.01em;
  font-variation-settings: "SOFT" 24, "WONK" 0, "opsz" 24;
}

.hero-lede {
  max-width: 46ch;
  margin: 24px 0 0;
  color: var(--ink-muted);
  font-size: var(--text-18);
  line-height: 1.65;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: 28px;
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  min-width: 48px;
  padding: 0 var(--space-5);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-14);
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease, transform 160ms ease;
}

.button:disabled,
.small-button:disabled,
.date-tile:disabled,
.slot-tile:disabled {
  cursor: not-allowed;
  opacity: 0.58;
}

/* Cognac, sampled off the leather - the accent belongs to the vessel. The old
   #ff7a3d appeared nowhere on the boat and fought the interior it sat in front of. */
.button-primary {
  color: #17100b;
  background: var(--cognac);
  border-color: var(--cognac);
}

.button-primary:hover:not(:disabled) {
  background: var(--cream);
  border-color: var(--cream);
}

.button-secondary {
  color: var(--ink);
  background: transparent;
  border-color: var(--line-strong);
}

.button-secondary:hover:not(:disabled) {
  color: var(--cream);
  border-color: var(--cognac);
  background: var(--surface-soft);
}

.button:hover:not(:disabled) {
  transform: translateY(-1px);
}

.stretch {
  width: 100%;
}

/* Was: a 720px studio render absolutely positioned at right:-80px, z-index:-1.
   On a 390px viewport it measured 390x243.75 at x=160 - starting 41% across, running
   160px off the right edge, and sitting UNDER hero-actions (368-477) and hero-status
   (529-681). The hard edge of its grey studio floor cut vertically through the CTA.

   Now a full-bleed cabin plate: it stands in for the WebGL interior, so the hero
   previews the finished effect instead of pasting a rectangle over the controls. */
.hero-boat {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 62% 70%;
  /* Heavily subdued on purpose. The dam water reads green through the windows, which
     fights the leather; desaturating lets the cognac carry the frame. This is a
     stand-in for the WebGL cabin, so it has to behave like ambience, not like a photo
     competing with the headline. */
  opacity: 0.4;
  filter: saturate(0.42) contrast(1.06) brightness(0.92);
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 24%, #000 60%, transparent 96%);
  mask-image: linear-gradient(180deg, transparent, #000 24%, #000 60%, transparent 96%);
  transition: opacity 500ms ease;
}

body.particle-background-ready[data-page="home"] .hero-boat {
  opacity: 0;
}

@media (min-width: 761px) {
  body.particle-background-ready[data-page="home"] .hero::after {
    background:
      linear-gradient(200deg, rgba(138, 79, 52, 0.12), transparent 55%),
      linear-gradient(90deg, rgba(10, 8, 6, 0.94) 8%, rgba(10, 8, 6, 0.68) 43%, rgba(10, 8, 6, 0.10) 70%, rgba(10, 8, 6, 0.24)),
      linear-gradient(180deg, rgba(10, 8, 6, 0.28), transparent 44%, rgba(10, 8, 6, 0.70));
  }
}

/* Keeps hero text off the brightest part of the plate at every width. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    /* warm cast pulls the remaining green back toward the cabin's own light */
    linear-gradient(200deg, rgba(138, 79, 52, 0.20), transparent 55%),
    linear-gradient(90deg, rgba(10, 8, 6, 0.95) 10%, rgba(10, 8, 6, 0.70) 48%, rgba(10, 8, 6, 0.42)),
    linear-gradient(180deg, rgba(10, 8, 6, 0.62), transparent 32%, rgba(10, 8, 6, 0.92));
}

/* Bordered pills read as chips in a dashboard. Hairline-divided figures read as
   a specification plate, which is what these actually are. */
/* Grid, not flex-wrap. Wrapping dropped the third figure onto its own line at 390px
   and left a dangling divider on the second - three fixed columns cannot orphan. */
.hero-status {
  align-self: end;
  display: grid;
  /* Capped columns, not thirds of the spine: at 1180px wide a third is ~393px and
     the three figures drift apart. The rule above them still spans the full spine. */
  grid-template-columns: repeat(3, minmax(0, 210px));
  justify-content: start;
  gap: 0;
  width: min(var(--content-max), 100%);
  max-width: min(var(--content-max), 100%);
  margin-inline: auto;
  margin-top: clamp(40px, 6vw, 72px);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
}

.hero-status span {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-1) clamp(12px, 3vw, 24px);
  border-right: 1px solid var(--line);
  color: var(--ink-faint);
  font-size: var(--text-12);
  letter-spacing: 0.1em;
  line-height: 1.35;
  text-transform: uppercase;
}

.hero-status span:first-child {
  padding-left: 0;
}

.hero-status span:last-child {
  border-right: 0;
  padding-right: 0;
}

.hero-status strong {
  margin-right: 0;
  color: var(--cream);
  font-family: var(--font-display);
  font-size: var(--text-30);
  font-weight: 400;
  letter-spacing: -0.01em;
  text-transform: none;
  font-variation-settings: "SOFT" 24, "WONK" 0, "opsz" 36;
}

.experience-band,
.booking-band,
.admin-band {
  background: linear-gradient(180deg, rgba(10, 8, 6, 0.72), rgba(10, 8, 6, 0.90));
}

.section-heading {
  width: min(var(--content-max), 100%);
  margin: 0 auto 28px;
}

.section-heading p:not(.eyebrow) {
  max-width: 690px;
  margin: 14px 0 0;
  color: var(--ink-muted);
}

.asset-grid {
  display: grid;
  grid-template-columns: 1.25fr 0.85fr;
  gap: var(--space-4);
  width: min(var(--content-max), 100%);
  margin: 0 auto;
}

.asset-card {
  position: relative;
  min-height: 280px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-strong);
}

.asset-card.wide {
  grid-row: span 2;
  min-height: 580px;
}

.asset-card img {
  width: 100%;
  height: 100%;
  min-height: inherit;
  object-fit: cover;
  opacity: 0.88;
}

.asset-card div {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: var(--space-4);
  background: linear-gradient(180deg, transparent, rgba(10, 8, 6, 0.94) 34%);
}

.asset-card h3 {
  max-width: 520px;
  color: var(--cream);
}

/* The exterior render ships on a near-white studio backdrop. Dropped in raw it read
   as an asset export parked between two warm photographs. Pulled down and warmed so
   it sits in the same room as the rest of the grid. */
.asset-card.is-render {
  background: var(--ground);
}

.asset-card.is-render img {
  opacity: 1;
  filter: brightness(0.42) contrast(1.16) saturate(0.78) sepia(0.22);
  transform: scale(1.06);
}

/* Was four columns of 260-280px inside 1320px. The calendar ran ~1500px tall while
   the slot panel ran ~550px, so three quarters of the band was dead space. Two
   columns, two rows: date + slot, then details + checkout. */
.booking-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: var(--space-5);
  width: min(var(--content-max), 100%);
  margin: 0 auto;
  align-items: start;
}

/* Every panel is a grid with a scale gap. This is the structural fix for the whole
   class of "the button is flush against the field" bug: children cannot end up
   touching by omission, because the container owns the spacing, not each child's
   ad-hoc margin. Two forms had a measured 0px gap above their submit button. */
.tool-panel {
  display: grid;
  align-content: start;
  gap: var(--space-5);
  padding: var(--space-6);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  backdrop-filter: blur(20px);
  /* A panel never lets its content out. min-width:0 stops a wide grid child from
     forcing the panel wider than its column; overflow-wrap catches long unbroken
     strings, which is what pushed a <strong> 9px past the date panel's edge. */
  min-width: 0;
  overflow-wrap: anywhere;
}

.tool-panel > * {
  min-width: 0;
}

.panel-heading {
  display: grid;
  gap: var(--space-2);
  margin-bottom: 0;
}

.panel-heading p {
  margin: 0;
  color: var(--ink-muted);
  font-size: var(--text-14);
}

/* Seven across, because that is what a calendar is. Three across made 21 days into
   a 7-row list ~1500px tall that read as a table of dates, not a month. */
.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--space-2);
}

.date-tile,
.slot-tile,
.segment,
.small-button {
  color: var(--ink);
  background: var(--surface-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease;
}

.date-tile:hover:not(:disabled),
.slot-tile:hover:not(:disabled),
.segment:hover:not(.is-active) {
  border-color: var(--line-strong);
  background: rgba(7, 84, 199, 0.10);
}

.date-tile {
  display: grid;
  gap: 0;
  align-content: start;
  justify-items: center;
  min-height: 78px;
  padding: var(--space-3) var(--space-1);
  text-align: center;
}

.date-tile span,
.date-tile small,
.slot-tile small,
.payload-list span,
.admin-list small {
  color: var(--ink-faint);
  font-size: var(--text-12);
}

/* At 7 across a tile is ~90px. The status word has to shrink or "Non-operational"
   wraps to three lines and doubles the row height. */
.date-tile small {
  font-size: 0.6875rem;
  line-height: 1.25;
  letter-spacing: 0.02em;
}

.date-tile span {
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-size: 0.625rem;
}

.date-tile strong {
  font-family: var(--font-display);
  font-size: var(--text-22);
  font-weight: 400;
  line-height: 1.15;
  font-variation-settings: "SOFT" 24, "WONK" 0, "opsz" 24;
}

.date-tile.is-selected,
.slot-tile.is-selected,
.segment.is-active {
  color: var(--cream);
  background: rgba(7, 84, 199, 0.12);
  border-color: var(--cognac);
}

.date-tile.is-selected strong,
.slot-tile.is-selected .slot-range {
  color: var(--cognac);
}

.slot-grid {
  display: grid;
  gap: var(--space-3);
}

.slot-tile {
  display: grid;
  gap: var(--space-2);
  min-height: 118px;
  padding: 12px;
  text-align: left;
}

.slot-range {
  color: var(--cream);
  font-family: var(--font-display);
  font-size: var(--text-18);
  font-weight: 400;
  letter-spacing: 0.01em;
  font-variation-settings: "SOFT" 24, "WONK" 0, "opsz" 20;
}

.meter {
  display: block;
  width: 100%;
  height: 8px;
  overflow: hidden;
  background: rgba(7, 84, 199, 0.12);
  border-radius: 999px;
}

.meter span {
  display: block;
  height: 100%;
  background: var(--cognac);
}

.slot-note {
  display: grid;
  gap: var(--space-2);
  min-height: 118px;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.slot-note span {
  color: var(--ink-muted);
}

.slot-note.is-open {
  border-color: rgba(112, 197, 155, 0.62);
}

.slot-note.is-blocked {
  border-color: rgba(255, 128, 111, 0.62);
}

label {
  display: grid;
  gap: var(--space-2);
  color: var(--ink-muted);
  font-size: var(--text-14);
}

input,
select {
  width: 100%;
  min-height: 46px;
  padding: 0 var(--space-3);
  color: var(--ink);
  background: rgba(7, 84, 199, 0.07);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
}

/* Icons inside fields get a real inset from the border. The browser's own select
   chevron ignores padding-right and parks itself a few px off the edge, which reads
   as the control being unfinished. Draw our own so the inset is a rule we control:
   --field-icon-inset, the same on every field on the site. */
select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: var(--space-6);
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='7' viewBox='0 0 10 7' fill='none'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%230754c7' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--field-icon-inset) center;
}

input[type="time"],
input[type="date"] {
  min-width: 0;
  /* Same inset, applied to the native picker glyph via the field's own padding. */
  padding-right: var(--field-icon-inset);
}

input[type="time"]::-webkit-calendar-picker-indicator,
input[type="date"]::-webkit-calendar-picker-indicator {
  margin-left: var(--space-2);
  margin-right: 0;
  cursor: pointer;
  opacity: 0.55;
  filter: invert(85%) sepia(18%) saturate(420%) hue-rotate(340deg);
  transition: opacity 140ms ease;
}

input[type="time"]:hover::-webkit-calendar-picker-indicator,
input[type="date"]:hover::-webkit-calendar-picker-indicator,
input[type="time"]:focus::-webkit-calendar-picker-indicator,
input[type="date"]:focus::-webkit-calendar-picker-indicator {
  opacity: 1;
}

select option {
  color: #061018;
}

.field-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
}

.booking-form {
  display: grid;
  gap: var(--space-4);
}

.segmented-control {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  border: 0;
}

.segmented-control legend {
  grid-column: 1 / -1;
  color: var(--ink-muted);
  font-size: var(--text-14);
}

.segment {
  min-height: 48px;
  padding: 8px;
}

#bookingPermission.is-ok {
  color: var(--success);
}

.price-list {
  display: grid;
  gap: var(--space-3);
  margin: 0;
}

.price-list div,
.payload-list li,
.admin-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--line);
}

.price-list dt,
.price-list dd {
  margin: 0;
}

.price-list dd,
.price-list strong {
  color: var(--ink);
}

.price-list .total {
  color: var(--cream);
  font-size: var(--text-18);
  font-weight: 700;
  border-bottom: 0;
}

.payfast-form {
  margin-bottom: 14px;
}

.payload-list,
.admin-list {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.payload-list li {
  align-items: flex-start;
  font-size: var(--text-12);
}

.payload-list strong {
  max-width: 58%;
  color: var(--ink-muted);
  text-align: right;
  overflow-wrap: anywhere;
}

/* Was three ~430px columns, which left the weekly-structure panel too narrow for a
   time field, a length field and an end time on one line - the native time picker's
   clock icon collided with the select next to it. Two columns, and the panel that
   actually needs room gets the full width. */
.admin-layout {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-5);
  width: min(var(--content-max), 100%);
  margin: 0 auto;
  align-items: start;
}

.admin-layout > .admin-form,
.admin-layout > .admin-toolbar,
.admin-layout > .admin-columns,
.admin-layout > .table-panel {
  grid-column: 1 / -1;
}

/* Explicit columns, not grid auto-flow.
   Auto-flow places by source order, so a very tall panel (Calendar controls, ~1500px)
   next to a short one (Promo codes, ~400px) leaves a 1100px hole, and the next panel
   starts a fresh row below the tall one rather than filling that hole. Declaring the
   columns lets the short panels stack against the tall one. */
.admin-columns {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-5);
  align-items: start;
}

.admin-col {
  display: grid;
  gap: var(--space-5);
  align-content: start;
  min-width: 0;
}

@media (max-width: 900px) {
  .admin-columns {
    grid-template-columns: minmax(0, 1fr);
  }
}

.admin-login {
  width: min(460px, 100%);
  margin: 0 auto;
  display: grid;
  gap: var(--space-4);
}

.admin-toolbar {
  --ink: #061a3a;
  --ink-muted: #405b78;
  --line: rgba(6, 51, 111, 0.17);
  --line-strong: rgba(6, 51, 111, 0.34);
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: rgba(230, 239, 247, 0.92);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.admin-toolbar .button-secondary {
  color: var(--ink);
  border-color: var(--line-strong);
}

.admin-toolbar .button-secondary:hover:not(:disabled) {
  color: #ffffff;
  background: var(--atlantic);
  border-color: var(--atlantic);
}

.admin-toolbar p {
  margin: 0;
  color: var(--ink-muted);
}

.admin-toolbar div,
.admin-actions,
.inline-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.admin-form {
  display: grid;
  gap: var(--space-4);
}

.day-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  border: 0;
}

.day-grid legend {
  grid-column: 1 / -1;
  color: var(--ink-muted);
  font-size: var(--text-14);
}

/* Was: checkbox + label side by side in a ~50px grid cell. The checkbox (20px) plus
   its margin and the tile padding took ~44px, so the label could not shrink and spilled
   out over the next tile. Now the whole tile is the control: the input is visually
   hidden but still focusable, and the tile itself carries the state. */
.day-grid label {
  display: grid;
  place-items: center;
  min-height: 52px;
  padding: 8px 4px;
  background: var(--surface-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink-muted);
  font-size: var(--text-14);
  cursor: pointer;
  user-select: none;
  transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease;
}

.day-grid label span {
  letter-spacing: 0.06em;
}

.day-grid input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.day-grid label:hover {
  border-color: var(--line-strong);
  color: var(--ink);
}

.day-grid label:has(input:checked) {
  color: var(--cream);
  background: rgba(7, 84, 199, 0.12);
  border-color: var(--cognac);
}

.day-grid label:has(input:focus-visible) {
  outline: 3px solid var(--cognac);
  outline-offset: 3px;
}

/* An open day is stated in words as well as colour - state never rests on hue alone. */
.day-grid label::after {
  content: "Closed";
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.day-grid label:has(input:checked)::after {
  content: "Open";
  color: var(--cognac);
}

/* --- Sittings editor ---------------------------------------------------- */

.date-slot-state {
  margin: 0;
  color: var(--ink-muted);
  font-size: var(--text-14);
}

.date-slot-state strong {
  color: var(--cream);
  font-weight: 600;
}

.date-slot-state em {
  color: var(--cognac);
  font-style: normal;
  font-weight: 600;
}

.sitting-editor {
  margin: 0;
  padding: var(--space-5);
  background: rgba(7, 84, 199, 0.05);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}

.sitting-count {
  display: flex;
  align-items: end;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--line);
}

.sitting-count label {
  display: grid;
  gap: var(--space-2);
  width: 132px;
}

.sitting-count p {
  flex: 1 1 220px;
  margin: 0 0 10px;
  color: var(--ink-faint);
  font-size: var(--text-14);
}

.sitting-list {
  display: grid;
  gap: var(--space-3);
  margin: 18px 0 0;
  padding: 0;
  list-style: none;
  counter-reset: sitting;
}

/* Fixed field widths, not fractions. On the full-width panel a 1fr time input grew
   to ~670px, which reads as an empty runway rather than a field. */
.sitting-row {
  display: grid;
  grid-template-columns: 34px minmax(120px, 190px) minmax(130px, 230px) minmax(0, 1fr);
  align-items: end;
  gap: var(--space-4);
  padding: 12px 16px;
  background: var(--surface-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.sitting-index {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  margin-bottom: 4px;
  color: var(--cognac);
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  font-family: var(--font-display);
  font-size: var(--text-14);
}

.sitting-field {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
}

.sitting-field > span {
  color: var(--ink-faint);
  font-size: var(--text-12);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.sitting-ends {
  display: grid;
  gap: var(--space-1);
  justify-items: end;
  padding-bottom: 12px;
  text-align: right;
}

.sitting-ends small {
  color: var(--ink-faint);
  font-size: var(--text-12);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.sitting-ends strong {
  color: var(--cream);
  font-family: var(--font-display);
  font-size: var(--text-18);
  font-weight: 400;
}

/* Overlap is a warning, never a block - staff may genuinely want back-to-back
   sittings that share a changeover. Say so and let them decide. */
.sitting-row.has-clash {
  border-color: var(--cognac-deep);
  background: rgba(7, 84, 199, 0.10);
}

.sitting-warning {
  margin: 14px 0 0;
  padding: 12px 14px;
  color: var(--ink);
  background: rgba(7, 84, 199, 0.12);
  border: 1px solid var(--cognac-deep);
  border-radius: var(--radius);
  font-size: var(--text-14);
}

/* Two columns with four children made the third child (the length select) flow back
   into the 34px index column - it measured 36px wide on a phone. Pin every field to
   column 2 and let the number badge span the rows beside them. */
@media (max-width: 620px) {
  .sitting-row {
    grid-template-columns: 34px minmax(0, 1fr);
    row-gap: 12px;
    align-items: start;
  }

  .sitting-index {
    grid-column: 1;
    grid-row: 1 / span 3;
    margin-bottom: 0;
  }

  .sitting-field,
  .sitting-ends {
    grid-column: 2;
    max-width: none;
  }

  .sitting-ends {
    justify-items: start;
    padding-bottom: 0;
    text-align: left;
  }
}

.check-row {
  display: flex;
  align-items: center;
  min-height: 46px;
  padding: 8px 12px;
  background: var(--surface-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.check-row input {
  width: 20px;
  min-height: 20px;
  margin: 0 10px 0 0;
  flex: none;
  accent-color: var(--cognac);
}

.date-admin,
.table-panel {
  display: grid;
  gap: var(--space-4);
}

.inline-form label {
  flex: 1 1 220px;
}

.small-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 44, not 40. These are the destructive ones - Remove, Cancel - and they were the
     only controls in the panel under the touch floor. */
  min-height: 44px;
  min-width: 72px;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-12);
  letter-spacing: 0.04em;
}

.table-panel {
  grid-column: span 2;
}

.table-scroll {
  overflow-x: auto;
}

table {
  width: 100%;
  min-width: 720px;
  border-collapse: collapse;
  font-size: var(--text-14);
}

th,
td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--line);
  text-align: left;
}

th {
  color: var(--cream);
  font-size: var(--text-12);
  text-transform: uppercase;
}

.event-list li {
  display: grid;
  align-items: start;
}

.toast {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 40;
  max-width: min(420px, calc(100vw - 36px));
  padding: var(--space-3) var(--space-4);
  color: var(--ink);
  background: var(--surface-strong);
  border: 1px solid var(--cognac);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity 180ms ease, transform 180ms ease;
}

.toast.is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (max-width: 1180px) {
  .booking-layout,
  .admin-layout {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .checkout-panel,
  .table-panel {
    grid-column: span 2;
  }
}

@media (max-width: 760px) {
  .site-header {
    align-items: flex-start;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
  }

  .site-nav {
    width: 100%;
  }

  .site-nav a {
    flex: 1 0 auto;
    justify-content: center;
  }

  .band {
    padding: var(--space-8) var(--space-4);
  }

  .hero {
    min-height: 68svh;
    padding-top: 34px;
  }

  .hero-copy {
    padding: var(--space-5) 0;
    background: transparent;
  }

  h1 {
    font-size: var(--text-44);
  }

  h2 {
    font-size: var(--text-30);
  }

  h3 {
    font-size: var(--text-18);
  }

  .hero-lede {
    font-size: var(--text-16);
  }

  .hero-boat {
    right: -160px;
    bottom: 92px;
    width: 720px;
    opacity: 0.34;
  }

  .asset-grid,
  .booking-layout,
  .admin-layout,
  .field-grid {
    grid-template-columns: 1fr;
  }

  .asset-card.wide,
  .checkout-panel,
  .table-panel {
    grid-column: auto;
    grid-row: auto;
  }

  .asset-card,
  .asset-card.wide {
    min-height: 270px;
  }

  .calendar-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .segmented-control {
    grid-template-columns: 1fr;
  }

  .day-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .admin-toolbar,
  .price-list div,
  .payload-list li,
  .admin-list li {
    align-items: stretch;
    flex-direction: column;
  }

  .payload-list strong {
    max-width: 100%;
    text-align: left;
  }

  .button {
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  /* Instant jumps instead of smooth scrolling is still honoured: it is a
     navigation behaviour, not one of the button effects. */
  html {
    scroll-behavior: auto;
  }

  /* .button:hover and the glass/carve effects are deliberately NOT disabled here.
     See carve.js for the instruction and the trade-off. */
  .toast {
    transition: none;
  }
}

/* A <legend> carries a 2px UA padding that lands off the spacing scale. */
legend {
  padding: 0;
}

/* ===========================================================================
   Multi-page chrome
   ========================================================================= */

.site-header [aria-current="page"] {
  color: var(--cream);
  background: var(--surface-soft);
}

.header-cta {
  min-height: 44px;
  padding: 0 var(--space-5);
}

.site-footer {
  position: relative;
  padding: var(--band-y) var(--gutter) var(--space-6);
  border-top: 1px solid var(--line);
  background: linear-gradient(180deg, transparent, rgba(10, 8, 6, 0.9));
}

.footer-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr));
  gap: var(--space-6);
  width: min(var(--content-max), 100%);
  margin: 0 auto;
}

.footer-brand p {
  max-width: 34ch;
  margin: var(--space-4) 0 0;
  color: var(--ink-muted);
  font-size: var(--text-14);
}

.footer-nav {
  display: grid;
  gap: var(--space-3);
  align-content: start;
}

.footer-nav h2 {
  margin: 0 0 var(--space-1);
  color: var(--cognac);
  font-family: var(--font-body);
  font-size: var(--text-12);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.footer-nav a,
.footer-nav span {
  color: var(--ink-muted);
  font-size: var(--text-14);
  text-decoration: none;
}

.footer-nav a:hover {
  color: var(--cream);
}

.footer-base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-4);
  width: min(var(--content-max), 100%);
  margin: var(--space-8) auto 0;
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
  color: var(--ink-faint);
  font-size: var(--text-12);
}

.footer-base p { margin: 0; }
.footer-base a { color: var(--ink-faint); }
.footer-base a:hover { color: var(--cognac); }

.page-head {
  padding-bottom: var(--space-6);
}

.page-head h1 {
  max-width: 20ch;
  font-size: var(--text-44);
}

.band-more {
  width: min(var(--content-max), 100%);
  margin: var(--space-8) auto 0;
}

.cta-band {
  text-align: left;
}

.spec-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-5);
  width: min(var(--content-max), 100%);
  margin: 0 auto;
  align-items: stretch;
}

.spec-grid p {
  margin: var(--space-3) 0 0;
  color: var(--ink-muted);
  font-size: var(--text-14);
}

/* ===========================================================================
   Booking console - one screen, no scrolling mid-booking
   ========================================================================= */

.book-main {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: var(--space-4);
  /* HEIGHT, not min-height. min-height sets a floor and the grid row then grows to
     fit its content - the panels measured 980px on a 900px viewport and the page
     scrolled 763px. A fixed height forces the panels to the screen and makes them
     scroll inside themselves instead. */
  height: calc(100svh - 72px);
  overflow: hidden;
  padding: var(--space-5) var(--gutter) var(--space-6);
}

.book-head {
  width: min(var(--content-max), 100%);
  margin: 0 auto;
}

/* Smaller than a normal page title: on a 800px laptop the full display size ate
   217px of the 728px available and pushed the pay button off screen. */
.book-head h1 {
  max-width: 24ch;
  margin: 0;
  font-size: var(--text-30);
}

.book-head .eyebrow {
  margin-bottom: var(--space-2);
}

.book-main .booking-layout {
  height: 100%;
  min-height: 0;
}

.book-main .booking-layout {
  /* The date column has a FLOOR, not a fraction. Seven tiles plus six 8px gaps plus
     the panel's 64px of padding needs 420px; below that the tiles measured 39.73px
     wide, under the 44px touch floor. */
  grid-template-columns: minmax(420px, 1.05fr) minmax(0, 0.8fr) minmax(0, 1.1fr);
  /* stretch, not start: this is what made the two panels in a row end at different
     heights - row 1 bottoms measured 153px apart. */
  align-items: stretch;
  min-height: 0;
}

/* Each panel scrolls inside itself. A date with eight sittings must not be able to
   push the pay button below the fold - that is the whole point of the console. */
.book-main .tool-panel {
  min-height: 0;
  overflow: hidden;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: var(--space-4);
}

.book-main .calendar-grid,
.book-main .slot-grid {
  min-height: 0;
  overflow-y: auto;
  align-content: start;
  padding-right: var(--space-1);
}

/* 8px gaps left the tiles 43.14px - 0.86px under the touch floor once the panel
   padding and the scroll gutter were taken out. A tighter gap buys the width back
   and reads better on a date picker anyway. */
.book-main .calendar-grid {
  gap: var(--space-1);
}

.book-main .detail-panel {
  grid-template-rows: auto minmax(0, 1fr) auto;
}

/* The FIELDS scroll; the submit button does not. Putting the button inside the
   scrolling area hid it at 1366x768 - the one viewport where the panel is shortest. */
.book-main .booking-form {
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  gap: var(--space-4);
  min-height: 0;
}

.book-main .booking-fields {
  display: grid;
  gap: var(--space-4);
  align-content: start;
  min-height: 0;
  overflow-y: auto;
  padding-right: var(--space-1);
}

.field-note {
  display: block;
  margin-top: var(--space-1);
  color: var(--ink-faint);
  font-size: var(--text-12);
  line-height: 1.4;
}

/* Pinned to the base of the panel. Never scrolls. */
.booking-summary {
  display: grid;
  gap: var(--space-3);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}

.payload-details summary {
  cursor: pointer;
  color: var(--ink-faint);
  font-size: var(--text-12);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.payload-details[hidden] { display: none; }

.payload-details .payload-list {
  max-height: 140px;
  overflow-y: auto;
  margin-top: var(--space-3);
}

/* On a phone the console cannot be one screen, and pretending otherwise breaks it.
   Release every height constraint and let the page scroll normally. */
@media (max-width: 900px) {
  .book-main {
    height: auto;
    min-height: 0;
    grid-template-rows: auto auto;
    overflow: visible;
    padding-inline: var(--space-2);
  }

  .book-main .booking-layout {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto;
    align-items: start;
    height: auto;
  }

  .book-main .tool-panel,
  .book-main .booking-form,
  .book-main .calendar-grid,
  .book-main .slot-grid {
    min-height: 0;
    max-height: none;
    overflow: visible;
  }

  .book-main .tool-panel,
  .book-main .booking-form {
    grid-template-rows: auto;
  }

  /* The month stays a calendar on phones. The earlier two-column fallback made
     thirty dates sixteen rows tall and pushed them through the next two panels. */
  .book-main .calendar-grid {
    grid-template-columns: repeat(7, minmax(0, 1fr));
    padding-right: 0;
  }

  /* Spend the calendar panel's horizontal padding on 44px date targets. */
  .book-main .calendar-panel {
    padding-inline: var(--space-1);
  }
}

/* ===========================================================================
   Account page
   ========================================================================= */

.account-layout {
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
  gap: var(--space-5);
  width: min(var(--content-max), 100%);
  margin: 0 auto;
  align-items: start;
}

.account-empty {
  margin: 0;
  color: var(--ink-muted);
  font-size: var(--text-14);
}

.booking-list {
  display: grid;
  gap: var(--space-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.booking-card {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-5);
  background: var(--surface-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.booking-card.is-cancelled {
  opacity: 0.6;
}

.booking-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.booking-card-head .eyebrow {
  margin: 0;
}

.booking-status {
  padding: var(--space-1) var(--space-3);
  color: var(--cream);
  background: rgba(192, 138, 98, 0.18);
  border: 1px solid var(--cognac);
  border-radius: var(--radius);
  font-size: var(--text-12);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.booking-card.is-cancelled .booking-status {
  color: var(--danger);
  background: transparent;
  border-color: var(--danger);
}

.booking-card h3 {
  margin: 0;
  font-size: var(--text-22);
}

.booking-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: var(--space-3);
  margin: 0;
}

.booking-facts div { display: grid; gap: var(--space-1); }
.booking-facts dt {
  color: var(--ink-faint);
  font-size: var(--text-12);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.booking-facts dd {
  margin: 0;
  color: var(--cream);
  font-family: var(--font-display);
  font-size: var(--text-18);
}

@media (max-width: 900px) {
  .account-layout,
  .footer-inner {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Footer links measured 22.39px tall - the only controls on the new pages under the
   44px touch floor. The text stays 14px; the target grows around it. */
.footer-nav a,
.footer-base a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.footer-nav span {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
}

/* --- Booking console corrections ---------------------------------------------
   Found by looking at a capture after the numbers said the layout was fine. */

/* Panel headings are h2 for document structure, but a page-title size inside a
   panel wastes the vertical budget the console is fighting for - "Choose a
   sitting" wrapped onto two lines. */
.book-main .panel-heading h2 {
  font-size: var(--text-22);
  max-width: none;
}

/* overflow-wrap:anywhere on the panel was breaking "Available" into "Availa/ble"
   inside a 46px tile. Tiles get normal word wrapping; long unbroken strings are
   not a risk in a date grid. */
.date-tile,
.date-tile * {
  overflow-wrap: normal;
  word-break: keep-all;
  hyphens: none;
}

/* The pay button only works once a booking exists. Showing it disabled the rest of
   the time cost ~90px of the panel that the form fields needed. */
.booking-summary .payfast-form:has(button[disabled]) {
  display: none;
}

.book-main .price-list div,
.book-main .price-list .total {
  padding: var(--space-2) 0;
}

/* Tighter form rhythm inside the console. Name and Email now share a row, and the
   note is one line under the pair rather than hanging off the email field. */
.book-main .field-note {
  margin: 0;
}

.book-main .booking-fields label {
  gap: var(--space-2);
}

.book-main .segmented-control legend {
  margin-bottom: var(--space-2);
}

/* Measured: the fields needed 334px and had 248 - short by 86. The price list was
   taking 209px for four rows (52px each) and the segmented control 100px. Tightening
   both inside the console buys back ~93px, which is where the fields go. */
.book-main .price-list {
  gap: var(--space-1);
}

.book-main .price-list div {
  padding: var(--space-1) 0;
}

.book-main .segment {
  padding: var(--space-2) var(--space-3);
  min-height: 44px;
}

.book-main .segmented-control {
  gap: var(--space-1);
}

/* Short laptops. Below ~860px of viewport height the console cannot show the page
   title AND the whole flow, so the title gives way first - it is the only thing on
   screen that isn't part of booking. */
@media (min-width: 901px) and (max-height: 880px) {
  .book-main {
    padding-top: var(--space-4);
    gap: var(--space-3);
  }

  .book-head .eyebrow { display: none; }
  .book-head h1 { font-size: var(--text-22); }
  .book-main .field-note { display: none; }
  .book-main .tool-panel { padding: var(--space-5); }
  .book-main .panel-heading p { display: none; }
}

/* Very short screens (1366x768 and similar). Trim the summary line that only repeats
   what the other two columns already show, and tighten the field rhythm. */
@media (min-width: 901px) and (max-height: 800px) {
  .book-main .booking-fields { gap: var(--space-3); }
  .book-main .price-list > div:first-child { display: none; }
  .book-main .booking-summary { padding-top: var(--space-3); }
  .book-main .book-head { display: none; }
}

/* ===========================================================================
   Month calendar

   Replaced a rolling 21-day window (which could never reach next month) with a
   real month grid you page through. The weekday header is rendered once above
   the grid, so each tile carries only its number and status.
   ========================================================================= */

.calendar-nav {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) 44px;
  align-items: center;
  gap: var(--space-2);
}

.calendar-nav strong {
  color: var(--cream);
  font-family: var(--font-display);
  font-size: var(--text-18);
  font-weight: 400;
  text-align: center;
  letter-spacing: 0.01em;
}

.calendar-step {
  display: grid;
  place-items: center;
  padding: 0;
  width: 44px;
  height: 44px;
  color: var(--ink);
  background: var(--surface-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: var(--text-18);
  line-height: 1;
  cursor: pointer;
  transition: border-color 140ms ease, color 140ms ease, background-color 140ms ease;
}

.calendar-step:hover:not(:disabled) {
  color: var(--cream);
  border-color: var(--cognac);
  background: rgba(7, 84, 199, 0.12);
}

.calendar-step:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.calendar-weekdays {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--space-1);
}

.calendar-weekdays span {
  padding-bottom: var(--space-1);
  color: var(--ink-faint);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-align: center;
  text-transform: uppercase;
}

/* Leading blanks so the 1st lands under its real weekday. */
.date-blank {
  display: block;
  min-height: 1px;
}

/* No weekday label on the tile any more - the header row carries it - so the tile
   is a number and a status word, and a six-row month still fits the panel. */
.date-tile {
  min-height: 56px;
  padding: var(--space-2) var(--space-1);
}

.date-tile.is-past {
  opacity: 0.28;
}

.book-main .calendar-panel {
  grid-template-rows: auto auto auto minmax(0, 1fr);
}

@media (min-width: 901px) and (max-height: 800px) {
  .date-tile { min-height: 48px; }
}

/* ===========================================================================
   Stepper — custom number picker

   The native number spinner is two grey arrows about 13px wide that belong to no
   design system and are far under a touch target. This replaces it entirely.
   ========================================================================= */

:root {
  --stepper-item-h: 44px;   /* must match ITEM_HEIGHT in stepper.js */
}

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

.stepper {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) 44px;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1);
  background: rgba(7, 84, 199, 0.07);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  transition: border-color 160ms ease, background-color 160ms ease;
}

.stepper:focus-within {
  border-color: var(--cognac);
  background: rgba(7, 84, 199, 0.10);
}

/* A small settle when a step button is pressed - enough to feel mechanical,
   short enough never to be in the way. */
.stepper.is-bumped .stepper input {
  transform: scale(1.06);
}

.stepper input[type="number"] {
  appearance: none;
  -moz-appearance: textfield;
  min-height: 44px;
  padding: 0;
  color: var(--cream);
  background: transparent;
  border: 0;
  border-radius: 0;
  font-family: var(--font-display);
  font-size: var(--text-22);
  font-weight: 400;
  font-variation-settings: "SOFT" 24, "WONK" 0, "opsz" 24;
  text-align: center;
  cursor: pointer;
  transition: transform 180ms cubic-bezier(0.2, 0.9, 0.3, 1.2);
}

.stepper input[type="number"]::-webkit-outer-spin-button,
.stepper input[type="number"]::-webkit-inner-spin-button {
  appearance: none;
  margin: 0;
}

.stepper input:focus-visible {
  outline: none;
}

.stepper-btn {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  color: var(--ink-muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  transition: color 140ms ease, background-color 140ms ease, border-color 140ms ease;
}

.stepper-btn svg {
  width: 12px;
  height: 12px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}

.stepper-btn:hover {
  color: var(--cream);
  background: rgba(7, 84, 199, 0.12);
  border-color: var(--cognac);
}

.stepper-btn:active {
  transform: translateY(1px);
}

/* --- the floating wheel --------------------------------------------------- */

.stepper-wheel {
  position: fixed;
  z-index: 60;
  overflow: hidden;
  background: rgba(4, 31, 79, 0.94);
  border: 1px solid var(--cognac);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  backdrop-filter: blur(20px) saturate(1.15);
  opacity: 0;
  transform: scale(0.94);
  transition: opacity 180ms ease, transform 220ms cubic-bezier(0.2, 0.9, 0.3, 1.1);
}

.stepper-wheel.is-open {
  opacity: 1;
  transform: scale(1);
}

.stepper-wheel-list {
  height: 100%;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
  scrollbar-width: none;
  touch-action: pan-y;
  cursor: grab;
  /* Fades the ends so numbers dissolve rather than being cut off by the border. */
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 26%, #000 74%, transparent);
  mask-image: linear-gradient(180deg, transparent, #000 26%, #000 74%, transparent);
}

.stepper-wheel-list::-webkit-scrollbar { display: none; }

.stepper-wheel.is-dragging .stepper-wheel-list {
  cursor: grabbing;
  scroll-snap-type: none;
}

.stepper-wheel-item {
  display: grid;
  place-items: center;
  width: 100%;
  height: var(--stepper-item-h);
  padding: 0;
  color: var(--ink);
  background: transparent;
  border: 0;
  scroll-snap-align: center;
  font-family: var(--font-display);
  font-size: var(--text-22);
  font-weight: 400;
  font-variation-settings: "SOFT" 24, "WONK" 0, "opsz" 24;
  cursor: inherit;
  transition: color 160ms ease;
  will-change: transform, opacity;
}

.stepper-wheel-item.is-centre {
  color: var(--cognac);
}

/* Two hairlines marking the selection line, the way a physical dial would. */
.stepper-wheel-rail {
  position: absolute;
  inset: 50% 0 auto;
  height: var(--stepper-item-h);
  transform: translateY(-50%);
  pointer-events: none;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

/* The stepper is a button too, so its motion is not gated either - same
   instruction as the carve and the glass specular. */

/* ===========================================================================
   LIQUID GLASS

   Technique researched via the refero-styles MCP, then rebuilt in this project's
   own palette. Two references, neither copied:

   Apple (styles.refero.design) — typographic discipline: negative tracking that
     tightens as size grows, weight-300 "whisper" subheads, one accent one job,
     hierarchy from surface shifts rather than decoration. Their palette is a light
     #f5f5f7 canvas with a blue accent and NO shadows; adopting that would have
     erased Nova Lounge, so only the method carried over.

   Authkit — "frosted glass cathedral at midnight". The load-bearing rule:
     "build elevation from inset frost highlights + soft outer halos rather than
     conventional drop-shadows" and "never solid borders — 1px inset strokes".
     Theirs is cool blue-white and their system forbids warm gradients. Ours is the
     exact inverse: warm cream frost, and cool tints are forbidden.

   Why glass suits THIS site specifically: the WebGL cabin will move behind these
   panels. Translucent layers over moving content is the problem glass solves.
   ========================================================================= */

:root {
  /* The frost is cream, not blue-white - it is lit by the cabin, not by moonlight. */
  --glass-tint: rgba(232, 210, 182, 0.045);
  --glass-tint-strong: rgba(232, 210, 182, 0.075);
  --glass-edge: rgba(232, 210, 182, 0.14);
  --glass-edge-lit: rgba(232, 210, 182, 0.30);
  --glass-halo: rgba(192, 138, 98, 0.10);
  --glass-blur: 22px;

  /* Apple's tracking method: the bigger the type, the tighter it sets. */
  --track-display: -0.028em;
  --track-heading: -0.018em;
  --track-body: -0.011em;
}

/* The material. Elevation is an inset top highlight plus a warm halo - never a
   drop shadow, which on a dark ground reads as a smudge rather than as depth. */
.glass {
  position: relative;
  isolation: isolate;
  background: linear-gradient(160deg, var(--glass-tint-strong), var(--glass-tint) 46%, transparent);
  border: 1px solid transparent;
  border-radius: var(--radius-lg);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  box-shadow:
    inset 0 1px 0 var(--glass-edge-lit),
    inset 0 0 42px var(--glass-halo),
    0 24px 60px rgba(0, 0, 0, 0.45);
  transition: box-shadow 240ms ease, transform 240ms cubic-bezier(0.2, 0.9, 0.3, 1);
}

/* Hairline edge drawn as a gradient stroke: bright where light would catch the
   top-left, fading away underneath. A solid 1px border cannot do this. */
.glass::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  padding: 1px;
  border-radius: inherit;
  background: linear-gradient(150deg, var(--glass-edge-lit), var(--glass-edge) 34%, transparent 70%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
}

/* The wet look: a specular smear that tracks the pointer. --mx/--my are written
   by glass.js on a rAF; with no pointer it rests off-panel and is invisible. */
.glass::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: radial-gradient(
    380px circle at var(--mx, 50%) var(--my, -30%),
    rgba(232, 210, 182, 0.13),
    rgba(192, 138, 98, 0.05) 38%,
    transparent 62%
  );
  opacity: 0;
  transition: opacity 320ms ease;
  pointer-events: none;
}

.glass:hover::after,
.glass:focus-within::after {
  opacity: 1;
}

.glass-lift:hover {
  transform: translateY(-3px);
  box-shadow:
    inset 0 1px 0 var(--glass-edge-lit),
    inset 0 0 52px var(--glass-halo),
    0 32px 70px rgba(0, 0, 0, 0.5);
}

/* No reduced-motion block for the glass specular. It used to carry
   `.glass::after { display: none }`, which hid the highlight outright - the CSS
   half of why the effect looked dead. Client instruction: these run always. */

/* --- Home page: glass sections ------------------------------------------- */

/* Apple's tracking method applied to our own faces: the larger the type, the
   tighter it sets. That negative tracking is what makes big display type read as
   architecture rather than as enlarged body copy. */
h1 { letter-spacing: var(--track-display); }
h2, h3 { letter-spacing: var(--track-heading); }
.hero-lede,
.section-heading p:not(.eyebrow) { letter-spacing: var(--track-body); }

/* The "whisper voice" - a subhead at 300 says the same words more quietly. */
.hero-lede {
  font-weight: 300;
}

.hero-status {
  padding: var(--space-5) var(--space-6);
  border-top: 0;
}

.ways-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-5);
  width: min(var(--content-max), 100%);
  margin: 0 auto;
  align-items: stretch;
}

/* Rows, not align-content:start. The cards are equal height, but with content
   stacked from the top a 3-line description pushed its price rule 23px below the
   2-line card's. The description row takes the slack so the price line is level
   across all three - a rule that wanders is more obvious than one that is low. */
.way-card {
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  gap: var(--space-3);
  padding: var(--space-6);
}

.way-index {
  margin: 0;
  color: var(--cognac);
  font-family: var(--font-display);
  font-size: var(--text-18);
  letter-spacing: 0.08em;
}

.way-card h3 {
  margin: 0;
}

.way-card p {
  margin: 0;
  color: var(--ink-muted);
  font-size: var(--text-14);
}

.way-price {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--glass-edge);
}

.way-price strong {
  color: var(--cream);
  font-family: var(--font-display);
  font-size: var(--text-22);
  font-weight: 400;
}

.cta-panel {
  display: grid;
  justify-items: start;
  gap: var(--space-4);
  width: min(var(--content-max), 100%);
  margin: 0 auto;
  padding: clamp(32px, 5vw, 64px);
}

.cta-panel h2 {
  margin: 0;
  max-width: 18ch;
}

.cta-panel p {
  margin: 0;
  max-width: 46ch;
  color: var(--ink-muted);
}

.cta-panel .button {
  margin-top: var(--space-3);
}

/* The section that introduces the glass gets a warm floor-glow behind it, so the
   plates have something to be lit BY. Glass over flat black reads as grey plastic. */
.ways-band,
.cta-band {
  isolation: isolate;
}

.ways-band::before,
.cta-band::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(80% 60% at 50% 40%, rgba(192, 138, 98, 0.10), transparent 68%);
}

/* --- Liquid carve --------------------------------------------------------- */

:root {
  --carve-control-blob: rgba(192, 138, 98, 0.34);
  --carve-secondary-blob: rgba(192, 138, 98, 0.45);
  --carve-container-blob: rgba(192, 138, 98, 0.16);
  --carve-container-surface: rgba(232, 210, 182, 0.04);
  --carve-ghost-surface: rgba(232, 210, 182, 0.06);
}

.carve-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  z-index: 0;
}

.is-carved {
  position: relative;
  isolation: isolate;
}

/* Text and controls stay above the material. Media stays beneath it, allowing the
   same warm cursor pool to travel over photographs as well as plain panels. */
.is-carved > :not(.carve-svg):not(img):not(picture):not(video):not(canvas),
.carve-label {
  position: relative;
  z-index: 1;
}

[data-carve-kind="container"] > :is(img, picture, video, canvas) {
  position: relative;
  z-index: -1;
}

[data-carve-kind="button"] {
  --carve-blob: var(--carve-control-blob);
}

[data-carve-kind="container"] {
  --carve-blob: var(--carve-container-blob);
  --carve-surface: var(--carve-container-surface);
  cursor: default;
}

[data-carve-kind="container"].glass-lift:hover {
  transform: none;
}

.button-secondary {
  --carve-surface: var(--carve-ghost-surface);
  --carve-blob: var(--carve-secondary-blob);
}

.button-primary { --carve-blob: var(--cream); }

.stepper-btn {
  --carve-surface: var(--carve-container-surface);
}

/* Once enhanced, the liquid carve is the hover treatment. Keeping the old full
   surface swap underneath it turns the effect inside out and obscures its path. */
.button.is-carved:hover:not(:disabled) {
  transform: none;
}

.button-primary.is-carved:hover:not(:disabled) {
  color: #17100b;
  background: var(--cognac);
  border-color: var(--cognac);
}

.button-secondary.is-carved:hover:not(:disabled) {
  color: var(--ink);
  background: transparent;
  border-color: var(--line-strong);
}

:is(.date-tile, .slot-tile, .segment, .small-button, .calendar-step).is-carved:hover:not(:disabled) {
  color: var(--ink);
  background: var(--surface-soft);
  border-color: var(--line);
}

:is(.date-tile.is-selected, .slot-tile.is-selected, .segment.is-active).is-carved:hover:not(:disabled) {
  color: var(--cream);
  background: rgba(192, 138, 98, 0.16);
  border-color: var(--cognac);
}

.stepper-btn.is-carved:hover:not(:disabled) {
  color: var(--ink-muted);
  background: transparent;
  border-color: transparent;
}

/* ===========================================================================
   Home page scroll composition
   ======================================================================== */

.home-story {
  position: relative;
}

body[data-page="home"] .experience-band,
body[data-page="home"] .ways-band,
body[data-page="home"] .cta-band {
  background: transparent;
}

body[data-page="home"] .ways-band::before,
body[data-page="home"] .cta-band::before {
  display: none;
}

body[data-page="home"][data-copy-side="left"] .ambient-scrim {
  background:
    linear-gradient(90deg, rgba(10, 8, 6, 0.95) 8%, rgba(10, 8, 6, 0.74) 42%, rgba(10, 8, 6, 0.16) 72%, rgba(10, 8, 6, 0.46)),
    linear-gradient(180deg, rgba(10, 8, 6, 0.18), rgba(10, 8, 6, 0.34) 64%, rgba(10, 8, 6, 0.88));
}

body[data-page="home"][data-copy-side="right"] .ambient-scrim {
  background:
    linear-gradient(90deg, rgba(10, 8, 6, 0.42), rgba(10, 8, 6, 0.14) 30%, rgba(10, 8, 6, 0.72) 62%, rgba(10, 8, 6, 0.95) 92%),
    linear-gradient(180deg, rgba(10, 8, 6, 0.18), rgba(10, 8, 6, 0.36) 64%, rgba(10, 8, 6, 0.90));
}

body[data-page="home"][data-copy-side="full"] .ambient-scrim {
  background:
    linear-gradient(90deg, rgba(10, 8, 6, 0.62), rgba(10, 8, 6, 0.34) 50%, rgba(10, 8, 6, 0.62)),
    linear-gradient(180deg, rgba(10, 8, 6, 0.28), rgba(10, 8, 6, 0.52) 68%, rgba(10, 8, 6, 0.92));
}

.story-stage {
  display: grid;
  grid-template-columns: min(var(--content-max), 100%);
  justify-content: center;
  align-items: center;
  min-height: clamp(960px, 145svh, 1320px);
}

.story-spine {
  display: grid;
  width: min(var(--content-max), 100%);
  min-width: 0;
}

.story-copy {
  display: grid;
  gap: var(--space-5);
  width: min(var(--story-rail), 100%);
  min-width: 0;
}

.story-stage-copy-left .story-copy {
  justify-self: start;
}

.story-stage-copy-right .story-copy {
  justify-self: end;
}

.story-copy .eyebrow,
.story-copy h2,
.story-copy > p,
.floating-gallery-heading .eyebrow,
.floating-gallery-heading h2,
.floating-gallery-heading > p {
  margin: 0;
}

.story-copy > p,
.floating-gallery-heading > p {
  color: var(--ink-muted);
  font-weight: 300;
  line-height: 1.7;
}

.story-copy > .button {
  justify-self: start;
  margin-top: var(--space-2);
}

.story-facts {
  display: grid;
  gap: 0;
  margin: var(--space-3) 0 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.story-facts div {
  display: grid;
  grid-template-columns: 120px minmax(0, 1fr);
  gap: var(--space-4);
  padding: var(--space-4) 0;
}

.story-facts div + div {
  border-top: 1px solid var(--line);
}

.story-facts dt,
.story-facts dd {
  margin: 0;
}

.story-facts dt {
  color: var(--cognac);
  font-size: var(--text-12);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.story-facts dd {
  color: var(--cream);
}

.ways-list {
  display: grid;
  gap: 0;
  margin-top: var(--space-3);
  border-top: 1px solid var(--line);
}

.ways-list .way-card {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5) 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
}

.ways-list .way-card > div {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
}

.ways-list .way-card h3,
.ways-list .way-card p {
  margin: 0;
}

.ways-list .way-card > div p {
  color: var(--ink-muted);
  font-size: var(--text-14);
}

.ways-list .way-index {
  align-self: start;
  padding-top: var(--space-1);
}

.ways-list .way-price {
  display: grid;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  border: 0;
  text-align: right;
}

.ways-list .way-price strong,
.ways-list .way-price span {
  white-space: nowrap;
}

.ways-list .way-price span {
  color: var(--ink-faint);
  font-size: var(--text-12);
  text-transform: uppercase;
}

.floating-gallery-band {
  display: grid;
  align-content: center;
  gap: var(--space-7);
  min-height: clamp(1080px, 138svh, 1320px);
  overflow: hidden;
}

.floating-gallery-heading {
  display: grid;
  gap: var(--space-4);
  width: min(var(--content-max), 100%);
  margin-inline: auto;
}

.floating-gallery-heading > p {
  max-width: 48ch;
}

.floating-gallery {
  position: relative;
  width: min(var(--content-max), 100%);
  height: clamp(640px, 78svh, var(--gallery-max-height));
  margin-inline: auto;
  overflow: hidden;
  isolation: isolate;
  touch-action: pan-y;
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(180deg, transparent, #000 8%, #000 92%, transparent);
}

.floating-gallery-card {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  min-width: 44px;
  min-height: 44px;
  overflow: hidden;
  opacity: 0;
  border: 1px solid var(--line-strong);
  background: var(--ground-3);
  cursor: pointer;
  user-select: none;
  filter: drop-shadow(0 24px 32px rgba(0, 0, 0, 0.48));
  will-change: transform;
}

.floating-gallery.is-ready .floating-gallery-card {
  opacity: 1;
}

.floating-gallery-card.is-zoomed {
  filter: drop-shadow(0 32px 48px rgba(0, 0, 0, 0.68));
}

.floating-gallery-card:focus-visible {
  outline: 3px solid var(--cognac);
  outline-offset: 3px;
}

.floating-gallery-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

.floating-gallery-card:nth-child(3) img,
.floating-gallery-card:nth-child(5) img {
  filter: brightness(0.62) contrast(1.12) saturate(0.76) sepia(0.16);
}

.floating-gallery-card:nth-child(4) img {
  object-position: 72% center;
}

.floating-gallery-card:nth-child(6) img {
  object-position: 68% center;
}

.reservation-copy {
  padding-block: var(--space-8);
}

@media (max-width: 760px) {
  body[data-page="home"][data-copy-side] .ambient-scrim {
    background:
      linear-gradient(90deg, rgba(10, 8, 6, 0.82), rgba(10, 8, 6, 0.52) 54%, rgba(10, 8, 6, 0.68)),
      linear-gradient(180deg, rgba(10, 8, 6, 0.28), rgba(10, 8, 6, 0.60) 72%, rgba(10, 8, 6, 0.94));
  }

  .story-stage {
    min-height: 108svh;
  }

  .story-stage-copy-right .story-copy,
  .story-stage-copy-left .story-copy {
    justify-self: start;
  }

  .story-facts div {
    grid-template-columns: 96px minmax(0, 1fr);
  }

  .ways-list .way-card {
    grid-template-columns: 32px minmax(0, 1fr);
  }

  .ways-list .way-price {
    grid-column: 2;
    justify-items: start;
    text-align: left;
  }

  .floating-gallery-band {
    gap: var(--space-6);
    min-height: 1120px;
  }

  .floating-gallery {
    height: clamp(640px, 92svh, var(--gallery-max-height));
  }
}

body[data-page="home"] .eyebrow,
body[data-page="home"] .story-facts dt,
body[data-page="home"] .ways-list .way-index {
  color: #d5efff;
}

.page-head .eyebrow,
.book-head .eyebrow {
  color: #d5efff;
}

/* ===========================================================================
   Blue and silver identity

   Auros informed the restraint, scale, and open composition. Nova keeps its own
   subject: daylight on water, polished metal, and a luminous particle vessel.
   ======================================================================== */

:root {
  --glass-tint: rgba(227, 237, 245, 0.10);
  --glass-tint-strong: rgba(227, 237, 245, 0.18);
  --glass-edge: rgba(227, 237, 245, 0.24);
  --glass-edge-lit: rgba(255, 255, 255, 0.62);
  --glass-halo: rgba(100, 200, 255, 0.18);
  --carve-control-blob: rgba(19, 139, 255, 0.42);
  --carve-secondary-blob: rgba(100, 200, 255, 0.48);
  --carve-container-blob: rgba(227, 237, 245, 0.22);
  --carve-container-surface: rgba(227, 237, 245, 0.10);
  --carve-ghost-surface: rgba(227, 237, 245, 0.14);
  --track-display: 0;
  --track-heading: 0;
  --track-body: 0;
}

body,
#webglBackground {
  background:
    linear-gradient(25deg, rgba(255, 255, 255, 0.10), transparent 36%, rgba(185, 224, 248, 0.22) 72%, transparent),
    linear-gradient(135deg, #0643a4 0%, #0c6cdb 36%, #3caaf3 67%, #d7e6f0 100%);
}

.ambient-scrim {
  background:
    linear-gradient(180deg, rgba(3, 31, 84, 0.14), rgba(3, 29, 78, 0.46)),
    linear-gradient(90deg, rgba(4, 32, 84, 0.32), transparent 58%);
}

body.particle-background-ready[data-page="home"] .ambient-scrim,
body[data-page="home"][data-copy-side="left"] .ambient-scrim {
  background:
    linear-gradient(90deg, rgba(3, 24, 66, 0.88) 0%, rgba(5, 49, 116, 0.70) 36%, rgba(6, 71, 151, 0.12) 68%, rgba(6, 77, 158, 0.02)),
    linear-gradient(180deg, rgba(4, 42, 102, 0.08), rgba(3, 32, 82, 0.38));
}

body[data-page="home"][data-copy-side="right"] .ambient-scrim {
  background:
    linear-gradient(90deg, rgba(6, 77, 158, 0.02), rgba(6, 71, 151, 0.10) 32%, rgba(5, 49, 116, 0.70) 64%, rgba(3, 24, 66, 0.90) 100%),
    linear-gradient(180deg, rgba(4, 42, 102, 0.08), rgba(3, 32, 82, 0.40));
}

body[data-page="home"][data-copy-side="full"] .ambient-scrim {
  background: linear-gradient(180deg, rgba(3, 31, 84, 0.28), rgba(3, 29, 78, 0.56));
}

.site-header {
  color: var(--ink-navy);
  background: rgba(230, 239, 247, 0.88);
  border-bottom-color: rgba(6, 43, 96, 0.14);
  backdrop-filter: blur(24px) saturate(1.18);
}

.site-header .brand-mark {
  color: var(--ink-navy);
}

.site-header .brand-symbol {
  color: var(--atlantic);
  border-color: rgba(7, 84, 199, 0.54);
}

.site-header .site-nav a {
  color: #365472;
}

.site-header .site-nav a:hover,
.site-header [aria-current="page"] {
  color: var(--ink-navy);
  background: rgba(7, 84, 199, 0.08);
}

.brand-mark,
h1,
h2,
h3,
.hero-status strong,
.date-tile strong,
.way-price strong,
.stepper-wheel-item {
  font-family: var(--font-display);
  font-variation-settings: normal;
}

.brand-mark {
  font-weight: 600;
}

h1,
h2,
h3 {
  font-weight: 500;
}

h1 {
  line-height: 0.98;
}

h2 {
  line-height: 1;
}

h3 {
  line-height: 1.16;
}

.hero-lede,
.story-copy > p,
.floating-gallery-heading > p {
  font-weight: 400;
}

.eyebrow {
  color: var(--sky-blue);
  font-weight: 600;
}

.eyebrow::before {
  width: 32px;
  background: var(--silver);
}

.button-primary {
  color: #ffffff;
  background: var(--atlantic);
  border-color: rgba(255, 255, 255, 0.28);
}

.button-primary:hover:not(:disabled) {
  color: #ffffff;
  background: var(--ink-navy);
  border-color: var(--silver);
}

.button-secondary {
  color: var(--ink);
  background: rgba(227, 237, 245, 0.08);
  border-color: rgba(227, 237, 245, 0.52);
}

.button-secondary:hover:not(:disabled) {
  color: var(--ink-navy);
  background: var(--silver);
  border-color: var(--silver);
}

.button-primary.is-carved:hover:not(:disabled) {
  color: #ffffff;
  background: var(--atlantic);
  border-color: rgba(255, 255, 255, 0.28);
}

.hero::after {
  background:
    linear-gradient(90deg, rgba(3, 24, 66, 0.86) 5%, rgba(5, 48, 113, 0.60) 42%, rgba(8, 86, 170, 0.02) 72%),
    linear-gradient(180deg, rgba(5, 52, 118, 0.10), rgba(3, 27, 71, 0.30));
}

@media (min-width: 761px) {
  body.particle-background-ready[data-page="home"] .hero::after {
    background:
      linear-gradient(90deg, rgba(3, 24, 66, 0.88) 5%, rgba(5, 48, 113, 0.62) 42%, rgba(8, 86, 170, 0.02) 72%),
      linear-gradient(180deg, rgba(5, 52, 118, 0.06), rgba(3, 27, 71, 0.28));
  }
}

body[data-page="home"] .hero-status {
  padding: var(--space-5) 0 0;
  background: transparent;
  border-top: 1px solid var(--line);
  border-radius: 0;
  box-shadow: none;
  backdrop-filter: none;
}

body[data-page="home"] .hero-status::before,
body[data-page="home"] .hero-status::after {
  display: none;
}

.hero-status strong,
.story-facts dd,
.ways-list .way-price strong {
  color: var(--silver);
}

.experience-band,
.booking-band,
.admin-band,
.account-band,
.spec-band {
  background: transparent;
}

.tool-panel {
  --ink: #061a3a;
  --ink-muted: #405b78;
  --ink-faint: #526d88;
  --cognac: #0754c7;
  --cream: #0754c7;
  --surface: rgba(245, 249, 252, 0.94);
  --surface-strong: rgba(219, 232, 242, 0.78);
  --surface-soft: rgba(7, 84, 199, 0.08);
  --line: rgba(6, 51, 111, 0.17);
  --line-strong: rgba(6, 51, 111, 0.34);
  --carve-container-surface: rgba(7, 84, 199, 0.07);
  --carve-ghost-surface: rgba(7, 84, 199, 0.09);
  color: var(--ink);
  background: linear-gradient(145deg, rgba(249, 252, 254, 0.96), rgba(218, 232, 242, 0.90));
  border-color: rgba(255, 255, 255, 0.60);
  box-shadow: 0 24px 64px rgba(4, 31, 78, 0.20), inset 0 1px 0 #ffffff;
  backdrop-filter: blur(28px) saturate(1.08);
}

.tool-panel .button-primary {
  color: #ffffff;
}

.tool-panel .button-secondary {
  color: var(--ink);
  background: transparent;
  border-color: var(--line-strong);
}

.tool-panel .button-secondary:hover:not(:disabled) {
  color: #ffffff;
  background: var(--atlantic);
  border-color: var(--atlantic);
}

.date-tile.is-selected,
.slot-tile.is-selected,
.segment.is-active,
:is(.date-tile.is-selected, .slot-tile.is-selected, .segment.is-active).is-carved:hover:not(:disabled) {
  color: var(--atlantic);
  background: rgba(7, 84, 199, 0.12);
  border-color: var(--atlantic);
}

.date-tile.is-selected strong,
.slot-tile.is-selected .slot-range {
  color: var(--atlantic);
}

.booking-status {
  color: var(--atlantic);
  background: rgba(7, 84, 199, 0.10);
  border-color: var(--atlantic);
}

.glass {
  background: linear-gradient(160deg, var(--glass-tint-strong), var(--glass-tint) 46%, rgba(227, 237, 245, 0.04));
  box-shadow:
    inset 0 1px 0 var(--glass-edge-lit),
    inset 0 0 42px var(--glass-halo),
    0 24px 60px rgba(4, 31, 78, 0.20);
}

.glass::after {
  background: radial-gradient(
    380px circle at var(--mx, 50%) var(--my, -30%),
    rgba(255, 255, 255, 0.22),
    rgba(100, 200, 255, 0.10) 38%,
    transparent 62%
  );
}

.asset-card div {
  background: linear-gradient(180deg, transparent, rgba(3, 29, 78, 0.92) 42%);
}

.asset-card.is-render img,
.floating-gallery-card:nth-child(3) img,
.floating-gallery-card:nth-child(5) img {
  filter: brightness(0.72) contrast(1.08) saturate(0.84) hue-rotate(3deg);
}

.floating-gallery-card {
  border-color: rgba(227, 237, 245, 0.58);
  background: var(--ground-3);
  filter: drop-shadow(0 24px 32px rgba(4, 31, 78, 0.32));
}

.site-footer {
  background: linear-gradient(180deg, rgba(4, 36, 92, 0.12), rgba(3, 25, 66, 0.94) 34%, #031742);
}

.site-footer .brand-mark,
.site-footer .footer-nav a:hover {
  color: var(--ink);
}

.site-footer .brand-symbol {
  color: var(--silver);
  border-color: rgba(227, 237, 245, 0.62);
}

@media (max-width: 760px) {
  :root {
    --text-44: 2.625rem;
    --text-64: 3.5rem;
  }

  .site-header {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-3);
  }

  .site-header .brand-mark {
    min-width: 0;
  }

  .site-header .brand-mark > span:last-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .header-cta {
    grid-column: 2;
    grid-row: 1;
    padding-inline: var(--space-4);
  }

  .site-nav {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    overflow: visible;
  }

  .site-nav a {
    min-width: 0;
    padding-inline: var(--space-2);
  }

  body[data-page="home"][data-copy-side] .ambient-scrim {
    background:
      linear-gradient(90deg, rgba(3, 38, 92, 0.46), rgba(6, 83, 170, 0.22) 72%, rgba(14, 110, 205, 0.08)),
      linear-gradient(180deg, rgba(4, 53, 120, 0.06), rgba(3, 40, 96, 0.34));
  }

  .hero::after,
  body.particle-background-ready[data-page="home"] .hero::after {
    background:
      linear-gradient(90deg, rgba(3, 38, 92, 0.50), rgba(6, 83, 170, 0.20) 74%, rgba(14, 110, 205, 0.06)),
      linear-gradient(180deg, rgba(4, 53, 120, 0.04), rgba(3, 40, 96, 0.28));
  }
}

.ways-list .way-card {
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
}

.ways-list .way-index {
  grid-column: 1;
  grid-row: 1;
  padding-top: 0;
  color: var(--sky-blue);
}

.ways-list .way-card > div {
  grid-column: 1;
  grid-row: 2;
}

.ways-list .way-price {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: end;
}

@media (max-width: 760px) {
  .ways-list .way-card {
    grid-template-columns: minmax(0, 1fr);
  }

  .ways-list .way-price {
    grid-column: 1;
    grid-row: 3;
    justify-items: start;
    text-align: left;
  }
}

/* One continuous atmosphere sits behind the fixed particle canvas. Scroll only
   changes these numeric transforms; no section owns or swaps the gradient. */
body {
  position: relative;
  isolation: isolate;
  background: #0754c7;
}

body::before {
  display: none;
}

.ambient-gradient {
  position: fixed;
  top: 50%;
  left: 50%;
  width: 145vmax;
  height: 145vmax;
  z-index: -4;
  pointer-events: none;
  background:
    radial-gradient(circle at 22% 24%, rgba(255, 255, 255, 0.62), transparent 18%),
    radial-gradient(circle at 73% 32%, rgba(112, 209, 255, 0.66), transparent 29%),
    radial-gradient(circle at 68% 82%, rgba(218, 234, 246, 0.72), transparent 24%),
    linear-gradient(128deg, #073b96 0%, #0d78dd 34%, #7dd4ff 68%, #dbe8f1 100%);
  transform: translate3d(-50%, -50%, 0) rotate(0deg);
  transform-origin: 50% 50%;
  will-change: transform;
}

#webglBackground {
  background: transparent;
}

.ambient-scrim,
body.particle-background-ready[data-page="home"] .ambient-scrim,
body[data-page="home"][data-copy-side="left"] .ambient-scrim,
body[data-page="home"][data-copy-side="right"] .ambient-scrim,
body[data-page="home"][data-copy-side="full"] .ambient-scrim {
  --scrim-focus-x: 8%;
  background:
    radial-gradient(
      ellipse 74% 118% at var(--scrim-focus-x) 48%,
      rgba(3, 22, 62, 0.78) 0%,
      rgba(4, 39, 93, 0.54) 38%,
      rgba(6, 69, 145, 0.12) 70%,
      transparent 88%
    ),
    linear-gradient(180deg, rgba(4, 45, 105, 0.08), rgba(3, 29, 76, 0.34));
  transition: none;
}

.hero::after,
body.particle-background-ready[data-page="home"] .hero::after {
  display: none;
}

@media (max-width: 760px) {
  .ambient-scrim,
  body.particle-background-ready[data-page="home"] .ambient-scrim,
  body[data-page="home"][data-copy-side] .ambient-scrim {
    background:
      radial-gradient(
        ellipse 104% 110% at var(--scrim-focus-x) 50%,
        rgba(3, 30, 76, 0.58) 0%,
        rgba(4, 50, 112, 0.34) 46%,
        rgba(9, 93, 181, 0.08) 78%,
        transparent 94%
      ),
      linear-gradient(180deg, rgba(4, 53, 120, 0.04), rgba(3, 40, 96, 0.28));
  }
}
