@charset "UTF-8";
/* ══════════════════════════════════════════════════════════════════════════════
   Aligned Hearts — the 2026 site

   The design is token-driven and otherwise styled inline, page by page. That is
   deliberate and it is how the comps were drawn: almost every rule in this file
   is either a custom property the inline styles read, a base reset, or a
   behaviour that cannot be expressed inline at all (hover, focus, breakpoints,
   reveal-on-scroll). Resist adding page styling here — it belongs next to the
   markup it dresses, where the comps put it.

   This file exists alongside the old site.css while pages are migrated one at a
   time. The layout picks which to load. When the last page moves, delete
   site.css, this file becomes site.css, and layouts/site.blade.php goes with it.

   Contents
     1  Tokens
     2  Base
     3  Hover and focus          — what inline styles cannot do
     4  Responsive               — the data-r contract
     5  Motion                   — reveal on scroll
     6  Forms
   ════════════════════════════════════════════════════════════════════════════ */

/* ── 1  Tokens ─────────────────────────────────────────────────────────────── */

:root {
  --ink:        #120C0A;
  --ink-soft:   #2A201C;
  --bone:       #F6F1EA;
  --bone-warm:  #EDE4D8;
  --ember:      #C4602E;
  --ember-deep: #8F3F1B;
  --sage:       #5C6B5A;
  --muted:      #8A7A70;
  --red:        #C8102E;

  /* The comps call for this on every solid-red hover but never defined it —
     the deep red is the one the "ways to work together" band is painted in. */
  --red-deep:   #9E0C24;

  --hair:       rgba(138, 122, 112, .22);
  --hair-dark:  rgba(246, 241, 234, .16);

  --display: 'Newsreader', Georgia, 'Times New Roman', serif;
  --body:    'Hanken Grotesk', Helvetica, Arial, sans-serif;

  --text:   clamp(17px, 16.6px + .15vw, 18px);
  --h1:     clamp(38px, 1.6rem + 3.4vw, 84px);
  --h2:     clamp(30px, 1.3rem + 2vw, 54px);
  --quote:  clamp(28px, 1.4rem + 1vw, 40px);
  --gutter: clamp(20px, 5vw, 72px);
  --sect:   clamp(72px, 40px + 5.5vw, 120px);

  --radius: 4px;
  --ease:   cubic-bezier(.22, 1, .36, 1);
}

/* ── 2  Base ───────────────────────────────────────────────────────────────── */

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bone);
  color: var(--ink);
  font-family: var(--body);
  font-size: var(--text);
  line-height: 1.6;
  font-feature-settings: "ss01";
}

h1, h2, h3, h4, p, figure { margin: 0; text-wrap: pretty; }

a {
  color: var(--red);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color .15s ease, text-decoration-color .15s ease;
}
a:hover { color: var(--ember-deep); }

button { font: inherit; cursor: pointer; color: inherit; }

:focus-visible { outline: 2px solid var(--ember); outline-offset: 2px; }

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

/* The comps set display inline on nearly everything, and an inline
   display:grid outranks the user-agent rule for [hidden] — so a hidden
   element stays on screen. Anything toggled with the hidden attribute needs
   this or it never hides. */
[hidden] { display: none !important; }

/* Small caps labels must not break across lines. */
a[style*="text-transform:uppercase"],
button[style*="text-transform:uppercase"] { white-space: nowrap; }

table { border-collapse: collapse; }

/* The skip link, visible only once it has focus. */
.skip-link {
  position: absolute;
  left: 8px;
  top: -60px;
  z-index: 100;
  background: var(--bone);
  color: var(--ink);
  padding: 10px 14px;
  border-radius: var(--radius);
  text-decoration: none;
  transition: top .15s ease;
}
.skip-link:focus { top: 8px; }

/* ── 3  Hover and focus ────────────────────────────────────────────────────── */
/* The comps express hover with a style-hover attribute their tool understands.
   These classes are the standards-CSS equivalent, named for what they do. */

/* Each button and link carries its colours inline, which beats a class, so
   the hover colours are !important — without it most of them never showed.
   Every change is one you can see: dark goes red, white goes dark, an
   outline fills in. */
.hv-ember:hover      { color: var(--ember) !important; }
.hv-ember-deep:hover { color: var(--ember-deep) !important; }
.hv-bone:hover       { color: var(--bone) !important; }
.hv-blush:hover      { color: #F6D7DB !important; }
.hv-blush-pale:hover { color: #FBEEEF !important; }
.hv-red-deep:hover   { color: var(--red-deep) !important; }
.hv-red:hover        { color: var(--red) !important; }
.hv-red-rule:hover   { color: var(--red) !important; border-color: var(--red) !important; }

/* Solid dark (ink) buttons → red. */
.hv-fill-ink:hover   { background: var(--red) !important; border-color: var(--red) !important; color: #FFFFFF !important; }
/* The round social icons → red. */
.hv-fill-red:hover   { background: var(--red) !important; color: #FFFFFF !important; }
/* Deep-red and ink submit buttons → bright red. */
.hv-fill-ember:hover { background: var(--red) !important; border-color: var(--red) !important; color: #FFFFFF !important; }
/* Outlines on a light ground → filled ink. */
.hv-fill-bone:hover, .hv-border-ink:hover { background: var(--ink) !important; border-color: var(--ink) !important; color: var(--bone) !important; }
/* Outlines on a dark or red ground → filled white. */
.hv-fill-bone-faint:hover, .hv-btn-outline-light:hover { background: #FFFFFF !important; border-color: #FFFFFF !important; color: var(--ink) !important; }
/* Solid white buttons on a dark or red ground → ink. */
.hv-btn-light:hover  { background: var(--ink) !important; color: #FFFFFF !important; }

/* Any other link that sets its own colour still changes on hover. */
a:not([class*="hv-"]):not([aria-label]):hover { color: var(--ember-deep) !important; }

/* ── 3b  Legal prose ───────────────────────────────────────────────────────
   The eight legal pages are the one place the comps style plain elements
   rather than every node individually — the body of a policy is a list of
   paragraphs, lists and the odd table, and there are eighty sections of it.
   Scoped to .legal so nothing here leaks into a page that styles inline. */

/* The comps set a numbered list a touch tighter than a bulleted one. */
.legal ul,
.legal ol      { margin: 0; padding-left: 22px; display: grid; gap: 10px; }
.legal ol      { gap: 8px; }
.legal h3      { font-family: var(--display); font-weight: 500; font-size: 22px; line-height: 1.25; margin-top: 8px; }
.legal table   { width: 100%; border-collapse: collapse; font-size: 17px; }
.legal th      { text-align: left; font-weight: 600; font-size: 14px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); padding: 12px 16px 12px 0; border-bottom: 1px solid var(--muted); }
.legal td      { padding: 16px 16px 16px 0; border-bottom: 1px solid var(--hair); vertical-align: top; }
.legal td:first-child { font-weight: 600; }

/* A policy can hold a wide retention table; let it scroll rather than push
   the page sideways on a phone. */
.legal__scroll { overflow-x: auto; }

/* The two tinted panels the policies use to lift something out of the run of
   text. A note is an aside; an alert is the paragraph someone will be cross
   about having missed, so it takes the red edge and a full border. */
/* Block, not grid, and no gap: that is how the comps draw them, and with the
   reset zeroing paragraph margins a multi-paragraph panel runs together. Only
   one panel on the site has more than a single paragraph — the emergency
   numbers on the Safety page — and it is flagged in docs/BACKLOG.md rather
   than quietly given air the design does not have. */
.legal-note,
.legal-alert {
  background: #FAF7F3;
  border-radius: var(--radius);
  padding: clamp(20px, 3vw, 32px);
}
.legal-note  { border-left: 3px solid var(--ink); }
.legal-alert { border: 1px solid var(--muted); border-left: 3px solid var(--red); }

/* The statutory notices: the CCPA do-not-sell statement, the Texas DPSA
   sensitive-data notice, the arbitration and class-action waivers. Several of
   the statutes behind these require the disclosure to be conspicuous, so the
   caps and the weight are doing legal work, not visual work. Do not quieten
   them down because they shout. */
.legal-shout {
  font-size: 17px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .02em;
  line-height: 1.5;
}

/* ── 3a  Choice cards ──────────────────────────────────────────────────────
   The booking page's package and time choices. The comp draws them as
   aria-pressed buttons; here they are labels wrapping a radio, so the form
   still submits a value with no script running. That makes the chosen state a
   matter of :checked rather than a class some JavaScript remembered to add —
   which is why it survives a validation bounce with old() re-checked. */

.choice { position: relative; cursor: pointer; }
.choice input { position: absolute; opacity: 0; width: 0; height: 0; }
.choice:has(input:checked) { border-color: var(--ink); }
.choice input:checked ~ .choice__bar { background: var(--red); }
.choice input:focus-visible ~ .choice__bar { background: var(--ember); }

/* The focus ring has to come from the label: the input it belongs to is
   zero-sized, so an outline on it would be invisible. */
.choice:has(input:focus-visible) { outline: 2px solid var(--ember); outline-offset: 2px; }

.choice[data-taken="true"] { opacity: .4; pointer-events: none; }

/* Package cards, as the comp draws them: white with a muted hairline; the
   chosen one takes the warm ground, a 2px red-deep edge and the red rule. */
.pkg { text-align: left; background: #FFFFFF; border: 1px solid var(--muted); border-radius: var(--radius); padding: 24px; display: grid; gap: 10px; transition: background .15s ease, border-color .15s ease; }
.pkg:hover { border-color: var(--ink); }
.pkg .choice__bar { height: 2px; background: transparent; transition: background .15s ease; }
.pkg:has(input:checked) { background: var(--bone-warm); border: 2px solid var(--red-deep); padding: 23px; }
.pkg input:checked ~ .choice__bar { background: var(--red-deep); }

/* The month calendar. Open days are white with a muted edge; the chosen day
   is red-deep; a day with hours but nothing left is struck through; closed,
   past and out-of-range days are quiet and cannot be pressed. */
.cal-day { min-height: 52px; background: transparent; color: var(--muted); border: 1px solid var(--hair); border-radius: var(--radius); font-size: 17px; cursor: not-allowed; transition: background .15s ease, border-color .15s ease; }
.cal-day[data-state="open"] { background: #FFFFFF; color: var(--ink); border-color: var(--muted); cursor: pointer; }
.cal-day[data-state="open"]:hover { border-color: var(--ink); }
.cal-day[data-state="full"] { text-decoration: line-through; }
.cal-day[aria-pressed="true"] { background: var(--red-deep); color: #FFFFFF; border-color: var(--red-deep); }

/* "Change" beside the time zone: a text link that is really a button. */
.tz-change { margin-left: 6px; padding: 0; background: none; border: 0; font: inherit; color: var(--red-deep); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.tz-change:hover { color: var(--ink); }

/* The month arrows beside the calendar's title. */
.cal-nav { width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; background: #FFFFFF; color: var(--ink); border: 1px solid var(--muted); border-radius: var(--radius); font-size: 24px; line-height: 1; cursor: pointer; transition: border-color .15s ease; }
.cal-nav:hover { border-color: var(--ink); }
.cal-nav:disabled { background: transparent; color: var(--muted); border-color: var(--hair); cursor: not-allowed; }

/* Times: the chosen one inverts to ink; taken ones are struck through. */
.time { min-height: 52px; padding: 0 12px; display: flex; align-items: center; justify-content: center; background: #FFFFFF; color: var(--ink); border: 1px solid var(--muted); border-radius: var(--radius); font-size: 16px; transition: background .15s ease, border-color .15s ease; }
.time:hover { border-color: var(--ink); }
.time:has(input:checked) { background: var(--ink); color: var(--bone); border-color: var(--ink); }
.time--taken, .time--taken:hover { background: transparent; color: var(--muted); border-color: var(--hair); text-decoration: line-through; cursor: not-allowed; }
.time[hidden] { display: none; }

/* ── 4  Responsive ─────────────────────────────────────────────────────────── */
/* The comps mark responsive intent with data-r on the element. Keeping that
   contract means the markup here and the markup in the comps stay comparable,
   which matters when a page is redrawn. */

[data-r="show-m"]       { display: none; }
[data-r="show-block-m"] { display: none; }

@media (max-width: 1023px) {
  [data-r="cols3"]  { grid-template-columns: 1fr !important; }
  [data-r="cols5"]  { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  [data-r="hide-m"] { display: none !important; }
  [data-r="show-m"] { display: flex; }
  [data-r="show-block-m"] { display: block !important; }
  [data-r="cols"]   { grid-template-columns: 1fr !important; }
  [data-r="cols"] > * { grid-column: auto !important; }
  [data-r="col-m"]  { flex-direction: column !important; align-items: flex-start !important; }
  [data-r="span-m"] { grid-column: 1 / -1 !important; }
  [data-indent]     { margin-left: 0 !important; }

  /* Footer columns collapse to accordions below the desktop breakpoint. */
  [data-foot] [data-foot-body] { display: none !important; }
  [data-foot][data-open="true"] [data-foot-body] { display: grid !important; }
}

@media (min-width: 1024px) {
  [data-foot-head] { display: none !important; }
}

@media (max-width: 767px) {
  [data-r="cols4"]     { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  [data-r="cols2"]     { grid-template-columns: 1fr !important; }
  [data-r="cols2"] > * { grid-column: auto !important; }
  [data-r="cell-note"] { display: none; }
  [data-r="pad-m"]     { padding-top: 24px !important; padding-bottom: 24px !important; }
}

/* ── 5  Motion ─────────────────────────────────────────────────────────────── */

[data-reveal] {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity .4s var(--ease), transform .4s var(--ease);
}
[data-reveal].in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
  [data-reveal] { opacity: 1; transform: none; }
}

/* ── 6  The Five Alignments ────────────────────────────────────────────────── */
/* The one hover in the comps that changes six things at once, so it could not
   be written as an inline style. Pure CSS rather than the mockup's mouse
   handlers: it then works for keyboard focus too, which the original did not. */

.five:hover,
.five:focus-within {
  background: rgba(246, 241, 234, .05);
  transform: translateY(-4px);
}
.five:hover .five__glyph,
.five:focus-within .five__glyph { transform: rotate(-6deg) scale(1.08); }



.five:hover .five__rule,
.five:focus-within .five__rule { width: 100%; }

.five:hover .five__body,
.five:focus-within .five__body { color: #F1E9DE; }

/* ── 7  Image placeholders ─────────────────────────────────────────────────── */
/* Where a photograph will go. Drawn the way the comps draw it: a dashed ring
   in currentColor at low opacity, a mark, and the art-direction brief in
   place, so the shot list travels with the build and every empty slot reads
   the same whether it sits on bone or on ink.
   The ring is a pseudo-element rather than a border on the figure so its
   opacity does not drag the caption down with it. */

.slot {
  position: relative;
  display: grid;
  place-items: center;
  align-content: center;
  gap: 10px;
  aspect-ratio: var(--slot-ratio, 3 / 2);
  padding: 16px;
  text-align: center;
  overflow: hidden;
  color: inherit;
}

.slot::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 1.5px dashed currentColor;
  border-radius: inherit;
  opacity: .35;
  pointer-events: none;
}

/* A picture mark: a frame with a sun and a horizon, at the comps' weight. */
.slot__mark {
  position: relative;
  width: 30px;
  height: 24px;
  border: 1.5px solid currentColor;
  border-radius: 3px;
  opacity: .45;
}
.slot__mark::before {
  content: "";
  position: absolute;
  left: 5px;
  top: 5px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
}
.slot__mark::after {
  content: "";
  position: absolute;
  left: 2px;
  right: 2px;
  bottom: 3px;
  height: 8px;
  border-top: 1.5px solid currentColor;
  transform: skewY(-14deg);
  transform-origin: left;
}

.slot__brief {
  position: relative;
  max-width: 34ch;
  font-size: 13px;
  line-height: 1.45;
  font-weight: 500;
  letter-spacing: .01em;
  opacity: .75;
}

/* Filled slots are a plain image; no ring, no brief. Block, not the grid the
   empty slot uses: in a grid the image kept its natural height and was
   centred, so a tall app screen showed its middle whatever object-position
   asked for. */
.slot--photo { display: block; padding: 0; }
.slot--photo::after { display: none; }
.slot--photo img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* An app screenshot, shown whole: the full height of the slot, centred, with
   a phone screen's corners and a lift off whatever panel it sits on. */
.slot--screen { display: flex; align-items: center; justify-content: center; padding: clamp(12px, 2vw, 24px); }
.slot--screen img {
  width: auto;
  max-width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: clamp(10px, 1.4vw, 18px);
  box-shadow: 0 1px 2px rgba(18, 12, 10, .12), 0 12px 32px rgba(18, 12, 10, .18);
}

/* A cut-out figure (transparent PNG/WebP): the whole person, feet — well,
   shoulders — on the bottom edge, over a warm bone-to-ember ground so the
   empty space reads as light rather than as a gap. */
.slot--cutout {
  background:
    radial-gradient(120% 80% at 50% 100%, rgba(196, 96, 46, .30), rgba(196, 96, 46, 0) 70%),
    linear-gradient(180deg, var(--bone) 0%, var(--bone-warm) 100%);
}
.slot--cutout img { object-fit: contain; object-position: center bottom; }

/* A slot asked to fill its parent has no ratio of its own. */
.slot[style*="height:100%"] { aspect-ratio: auto; }

/* ── 8  Disclosure ─────────────────────────────────────────────────────────── */
/* <details> carries the FAQ so it works without script. These only remove the
   browser's own marker — the comps draw their own + sign — and turn it when
   the panel opens. */

summary::-webkit-details-marker { display: none; }
summary::marker { content: ''; }

details[open] > summary span[aria-hidden] { transform: rotate(45deg); }
summary span[aria-hidden] {
  display: inline-block;
  transition: transform .2s var(--ease);
}

/* ── 9  Forms ──────────────────────────────────────────────────────────────── */
/* The comps draw inputs inline. These are the states they cannot: placeholder
   colour, invalid, and the disabled button while a form is in flight. */

input, textarea, select { font: inherit; color: inherit; }
input::placeholder, textarea::placeholder { color: var(--muted); opacity: 1; }

[data-invalid="true"] { border-color: #E8A07A !important; }

button[disabled], a[aria-disabled="true"] { opacity: .6; cursor: not-allowed; }

/* Read out by screen readers, not shown: "(opens in a new tab)". */
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* The honeypot field: present for robots, gone for everyone else. */
.hp-field {
  position: absolute !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* "Or talk to Samuel first": the button sits on the right edge beside the
   text, and under it (left) once the columns stack on a phone. */
[data-cta-end] { justify-self: end; }
@media (max-width: 1023px) { [data-cta-end] { justify-self: start; } }

/* The header sticks to the top; a jump link lands below it, not under it. */
html { scroll-padding-top: calc(var(--header-h, 0px) + 12px); }

/* Side menus and pictures that follow you down the page beside the text do
   so on wide screens only; stacked on a phone they would sit over it. */
@media (max-width: 1023px) { [data-stick-wide] { position: static !important; } }

/* ── Hover, across the site ──────────────────────────────────────────────
   One layer of movement on top of the colour changes above: links draw an
   underline, buttons and badges lift, cards rise and their photos lean in.
   Only for a real pointer (no sticky hover on a phone after a tap), and
   none of the movement for anyone who has asked for reduced motion.
   Several elements carry an inline `transition: background …`, which would
   otherwise stop transforms animating — hence the !important on transition. */

/* Menu links: an underline that grows from the left. */
nav[aria-label="Primary"] a,
nav[aria-label="Primary mobile"] a,
footer a:not([aria-label]) {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1.5px;
  padding-bottom: 2px;
  transition: color .2s ease, background-size .3s ease !important;
}
nav[aria-label="Primary"] a[aria-current="page"] { background-size: 100% 1.5px; }

/* Buttons, social circles, store badges, cards and photos: ready to move. */
.hv-fill-ink, .hv-fill-red, .hv-fill-bone, .hv-fill-ember, .hv-fill-bone-faint, .hv-border-ink,
.hv-btn-light, .hv-btn-outline-light,
button[type="submit"], [data-submit],
a[aria-label="Download on the App Store"], a[aria-label="Get it on Google Play"],
[data-r="cols3"] > article, #app ul > li, .pkg, .cal-nav {
  transition: background-color .2s ease, color .2s ease, border-color .2s ease,
              transform .25s ease, box-shadow .25s ease, filter .25s ease !important;
}
.slot--photo:not(.slot--screen):not(.slot--cutout) img { transition: transform .8s cubic-bezier(.2, .7, .2, 1); }

@media (hover: hover) {
  nav[aria-label="Primary"] a:hover,
  nav[aria-label="Primary mobile"] a:hover,
  footer a:not([aria-label]):hover { background-size: 100% 1.5px; }

  details > summary { transition: color .2s ease; }
  details > summary:hover { color: var(--red-deep); }
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  /* Buttons lift, with a soft shadow under them. */
  .hv-fill-ink:hover, .hv-fill-red:hover, .hv-fill-bone:hover, .hv-fill-ember:hover,
  .hv-fill-bone-faint:hover, .hv-border-ink:hover, .hv-btn-light:hover, .hv-btn-outline-light:hover,
  button[type="submit"]:not(:disabled):hover, [data-submit]:not(:disabled):hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 22px -10px rgba(18, 12, 10, .45);
  }
  /* The round social icons grow a touch instead. */
  ul[aria-label="Social"] a:hover { transform: translateY(-2px) scale(1.08); box-shadow: none; }

  /* App store badges. */
  a[aria-label="Download on the App Store"]:hover,
  a[aria-label="Get it on Google Play"]:hover { transform: translateY(-3px); filter: drop-shadow(0 8px 12px rgba(0, 0, 0, .25)); }

  /* Cards rise; a photo inside leans in. */
  [data-r="cols3"] > article:hover { transform: translateY(-4px); box-shadow: 0 18px 36px -22px rgba(18, 12, 10, .55); }
  #services [data-r="cols3"] > article:hover { box-shadow: none; }
  #services [data-r="cols3"] > article img { transition: transform .35s ease; }
  #services [data-r="cols3"] > article:hover img { transform: scale(1.12) rotate(-4deg); }
  .pkg:hover { transform: translateY(-2px); box-shadow: 0 12px 24px -16px rgba(18, 12, 10, .45); }

  article:hover .slot--photo:not(.slot--screen):not(.slot--cutout) img,
  figure:hover > .slot--photo:not(.slot--screen):not(.slot--cutout) img,
  .slot--photo:not(.slot--screen):not(.slot--cutout):hover img { transform: scale(1.04); }

  /* The app's feature list: the line nudges across. */
  #app ul > li:hover { transform: translateX(6px); }
  #app ul > li:hover h3 { color: var(--red-deep); }
  #app ul > li h3 { transition: color .2s ease; }
}

/* The header: slides away just after the top, back in compact a little later
   (the script sets the classes). Smooth both ways; nothing moves for anyone
   who has asked for reduced motion. */
[data-site-header] {
  transition: transform .45s cubic-bezier(.2, .7, .2, 1), box-shadow .3s ease;
}
[data-site-header] > div,
[data-site-logo] { transition: padding .35s ease, height .35s ease; }
[data-site-header].is-hidden { transform: translateY(-100%); box-shadow: none; }
[data-site-header].is-compact { box-shadow: 0 10px 28px -18px rgba(18, 12, 10, .45); }
[data-site-header].is-compact > div { padding-top: 8px !important; padding-bottom: 8px !important; }
[data-site-header].is-compact [data-site-logo] { height: 48px !important; }
@media (max-width: 1023px) {
  [data-site-header].is-compact [data-site-logo] { height: 40px !important; }
}
/* The rails that stick beneath it follow it smoothly. */
[aria-label="Your booking so far"], [data-step-nav], [data-stick-wide] { transition: top .45s cubic-bezier(.2, .7, .2, 1); }
@media (prefers-reduced-motion: reduce) {
  [data-site-header], [data-site-header] > div, [data-site-logo],
  [aria-label="Your booking so far"], [data-step-nav], [data-stick-wide] { transition: none; }
}
/* Compact: the two rows close up, the social circles and the button shrink. */
[data-site-header] [data-r="hide-m"],
[data-site-header] ul[aria-label="Social"] a,
[data-site-header] a.hv-fill-ink { transition: gap .35s ease, width .35s ease, height .35s ease, padding .35s ease, background-color .2s ease, color .2s ease, transform .25s ease, box-shadow .25s ease !important; }
[data-site-header].is-compact [data-r="hide-m"] { gap: 6px !important; }
[data-site-header].is-compact ul[aria-label="Social"] a { width: 30px !important; height: 30px !important; }
[data-site-header].is-compact a.hv-fill-ink { padding: 8px 16px !important; font-size: 13px !important; }
[data-site-header].is-compact [data-site-logo] { height: 44px !important; }

/* A photo cropped to fit its space keeps its top (the faces) and loses the bottom. */
[data-crop-top] .slot--photo img { object-position: center top; }
[data-crop-top] { position: relative; }
[data-crop-top] > .slot { position: absolute; inset: 0; height: auto !important; }

/* Home: Samuel's card — logo on top, his cut-out on the bottom edge, over the
   same warm bone-to-ember ground the cut-out slot uses. */
.samuel-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(20px, 2.4vw, 32px);
  padding-top: clamp(28px, 3vw, 44px);
  border-radius: var(--radius);
  overflow: hidden;
  background:
    radial-gradient(120% 70% at 50% 100%, rgba(196, 96, 46, .28), rgba(196, 96, 46, 0) 70%),
    linear-gradient(180deg, var(--bone) 0%, var(--bone-warm) 100%);
}
.samuel-card img:last-child { transition: transform .8s cubic-bezier(.2, .7, .2, 1); transform-origin: center bottom; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .samuel-card:hover img:last-child { transform: scale(1.03); }
}

/* How it works: the sticky rail. A short label, then the step's picture fills
   the rest of the window's height. App screens stand on a warm glow so the
   phone reads as the subject rather than floating in an empty box; photos
   fill the frame. */
.hiw-rail {
  grid-column: 1 / span 5;
  position: sticky;
  top: calc(var(--header-h, 0px) + 84px);
  height: calc(100vh - var(--header-h, 0px) - 116px);
  min-height: 460px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: clamp(28px, 4vh, 48px) 0 8px;
}
.hiw-rail__frame {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--ink-soft);
}
.hiw-rail__frame .hiw-shot { position: absolute; inset: 0; transition: opacity .6s var(--ease); }
.hiw-shot--screen .slot {
  background:
    radial-gradient(70% 60% at 50% 55%, rgba(200, 16, 46, .30), rgba(200, 16, 46, 0) 70%),
    linear-gradient(180deg, #2A1F1B 0%, #1A1210 100%) !important;
}
.hiw-shot--screen .slot--screen { padding: clamp(20px, 3vh, 36px); }
.hiw-shot--screen .slot--screen img { box-shadow: 0 2px 4px rgba(0, 0, 0, .3), 0 24px 60px rgba(0, 0, 0, .55); }
/* Phones: the rail is hidden and each step shows its own picture. */
.hiw-shot--inline { margin-top: 24px; border-radius: var(--radius); overflow: hidden; height: 360px; }
.hiw-shot--inline.hiw-shot--screen { height: 460px; }

/* The three-up facts under a heading: stacked on phones, the dividers become
   rules between rows. */
@media (max-width: 1023px) {
  dl[data-r="cols3"] > div { padding: 14px 0 !important; border-left: 0 !important; }
  dl[data-r="cols3"] > div + div { border-top: 1px solid var(--hair-dark); }
}

/* A photo stretched to the height of the text beside it always covers. */
[data-crop-top] .slot img { width: 100%; height: 100%; object-fit: cover; }

/* Held off for one measurement (see stickyHeader in site-v2.js). */
[data-site-header].no-anim, [data-site-header].no-anim > div, [data-site-header].no-anim [data-site-logo] { transition: none !important; }
/* The header slides on the compositor; hint it so the slide never stutters. */
[data-site-header] { will-change: transform; }

/* ── "Almost ready" — the app badges before the app is in the stores ────────
   A native <dialog>, so the browser gives us the backdrop, the focus trap and
   Escape without a line of script. */
.soon {
  border: 0;
  padding: 0;
  max-width: 440px;
  width: calc(100% - 2 * var(--gutter));
  background: var(--bone);
  color: var(--ink);
  border-radius: calc(var(--radius) * 2);
  box-shadow: 0 24px 60px rgba(18, 12, 10, .28);
}
.soon::backdrop { background: rgba(18, 12, 10, .55); }

/* The dialog itself is the padded card; the close sits over its corner. */
.soon > * { margin: 0 32px; }
.soon__eyebrow {
  margin-top: 36px;
  font: 600 12px/1 var(--body);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
}
.soon__title {
  margin-top: 10px;
  font: 400 clamp(30px, 2rem + 1vw, 38px)/1.1 var(--display);
  letter-spacing: -.01em;
}
.soon__body {
  margin-top: 14px;
  font: 400 var(--text)/1.55 var(--body);
  color: var(--ink-soft);
}
.soon__cta {
  display: block;
  margin-top: 26px;
  padding: 15px 20px;
  background: var(--red);
  color: #fff;
  font: 600 15px/1 var(--body);
  letter-spacing: .02em;
  text-align: center;
  text-decoration: none;
  border-radius: var(--radius);
  transition: background .2s var(--ease);
}
.soon__cta:hover { background: var(--red-deep); }
.soon__dismiss {
  display: block;
  width: calc(100% - 64px);
  margin: 12px 32px 32px;
  padding: 4px;
  background: none;
  border: 0;
  font: 400 14px/1.4 var(--body);
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.soon__dismiss:hover { color: var(--ink); }
.soon__x {
  position: absolute;
  top: 10px;
  right: 12px;
  margin: 0;
  width: 40px;
  height: 40px;
  background: none;
  border: 0;
  font: 400 26px/1 var(--body);
  color: var(--muted);
  cursor: pointer;
}
.soon__x:hover { color: var(--ink); }

@media (prefers-reduced-motion: no-preference) {
  .soon[open] { animation: soon-in .28s var(--ease); }
  @keyframes soon-in { from { opacity: 0; transform: translateY(8px); } }
}
