/* site.css — Coffee Yard. Reads tokens.css; holds no raw colour, size or easing.

   Mobile first: the base rules are the phone layout, and (min-width: 48rem)
   widens it. Logical properties only, so the same rules serve Arabic (RTL, the
   default) and English. State is a data-* attribute set by site.js.

   Order: base, shared pieces, then the page top to bottom:
   masthead + phone menu, hero, coffee, hours + dial, find, contact, footer,
   dock, 404. */

/* ---------- Base ---------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  background: var(--maroon);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-block-start: var(--space-5);
}

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  background: var(--milk);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--fs-base);
  font-weight: var(--w-regular);
  line-height: var(--lh-body);
  --focus: var(--maroon);
}

h1, h2, p, ul, table { margin: 0; }
ul { padding: 0; list-style: none; }
img, svg, picture { display: block; }
img { max-inline-size: 100%; block-size: auto; }
a { color: inherit; }
button { font: inherit; color: inherit; }
[hidden] { display: none !important; }

:focus-visible {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-offset);
}

h2 {
  font-size: var(--fs-h2);
  font-weight: var(--w-heavy);
  line-height: var(--lh-display);
  text-wrap: balance;
}

/* ---------- Shared pieces ---------- */

.wrap {
  inline-size: min(100% - 2 * var(--gutter), var(--wrap));
  margin-inline: auto;
}

.visually-hidden {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  inset-block-start: var(--space-2);
  inset-inline-start: var(--space-2);
  z-index: calc(var(--z-header) + 1);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--milk);
  color: var(--maroon);
  font-weight: var(--w-medium);
  translate: 0 -200%;
}
.skip-link:focus { translate: 0 0; }

.icon {
  flex: none;
  inline-size: var(--icon);
  block-size: var(--icon);
  fill: none;
  stroke: currentColor;
  stroke-width: var(--icon-stroke);
  stroke-linecap: round;
  stroke-linejoin: round;
}
.icon--brand { fill: currentColor; stroke: none; }
[dir="rtl"] .icon--mirror { scale: -1 1; }

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-block-size: var(--tap);
  padding: var(--space-2) var(--space-5);
  border: var(--border) solid transparent;
  border-radius: var(--radius-pill);
  font-size: var(--fs-base);
  font-weight: var(--w-medium);
  line-height: var(--lh-snug);
  text-align: center;
  text-decoration: none;
  transition: background-color var(--dur-fast), color var(--dur-fast);
}
.button--light { background: var(--milk); color: var(--maroon); }
.button--light:hover { background: var(--sky); }
.button--ghost { border-color: var(--milk); color: var(--milk); }
.button--ghost:hover { background: var(--wash-on-dark); }
.button--brand { background: var(--maroon); color: var(--milk); }
.button--brand:hover { background: var(--maroon-deep); }

/* ---------- Masthead ---------- */

.masthead {
  position: relative;
  z-index: var(--z-header);
  background: var(--maroon);
  color: var(--milk);
  --focus: var(--milk);
}

.masthead__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-5);
  padding-block: var(--space-4);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--fs-lg);
  font-weight: var(--w-heavy);
  line-height: 1;
  text-decoration: none;
}
.brand img { inline-size: var(--logo); block-size: var(--logo); }

/* On the home pages the bar lies over the hero photo instead of above it. */
.masthead--over {
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  background: none;
}

.menu { flex: 1 0 100%; }

.menu__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--space-5);
}

.menu__link {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--tap);
  font-size: var(--fs-sm);
  font-weight: var(--w-medium);
  text-decoration: none;
}
.menu__link:hover {
  text-decoration: underline;
  text-decoration-thickness: var(--border);
  text-underline-offset: var(--underline-offset);
}

.menu__item--lang .menu__link {
  min-block-size: var(--tap-small);
  padding-inline: var(--space-4);
  border: var(--border) solid var(--line-on-dark);
  border-radius: var(--radius-pill);
}
.menu__item--lang .menu__link:hover {
  background: var(--wash-on-dark);
  text-decoration: none;
}

.menu-toggle { display: none; }

@media (min-width: 48rem) {
  .menu { flex: none; }
  .menu__item--lang { margin-inline-start: var(--space-2); }
}

/* The phone menu: with scripts on, the nav itself becomes a dark full-screen
   panel that grows as a circle from the menu button and shrinks back into it.
   site.js writes --menu-x / --menu-y (the button's centre), toggles data-open
   on the panel, and sets data-menu-open on <html> while it is open.

   Do not put transform, filter or backdrop-filter on .masthead: it would
   become the containing block for this fixed panel and clip it to the bar. */
@media (max-width: 47.99rem) {
  html[data-js][data-menu-open] { overflow: hidden; }

  html[data-js] .menu-above { position: relative; z-index: 1; }

  html[data-js] .menu-toggle {
    display: inline-grid;
    place-items: center;
    inline-size: var(--tap);
    block-size: var(--tap);
    padding: 0;
    border: var(--border) solid var(--line-on-dark);
    border-radius: 50%;
    background: none;
    color: var(--milk);
    cursor: pointer;
  }
  .menu-toggle__bars {
    display: grid;
    gap: var(--bar-gap);
    inline-size: var(--bar-width);
  }
  .menu-toggle__bars::before,
  .menu-toggle__bars::after {
    content: "";
    block-size: var(--bar);
    border-radius: var(--bar);
    background: currentColor;
    transition: translate var(--dur-fast), rotate var(--dur-fast);
  }
  .menu-toggle[aria-expanded="true"] .menu-toggle__bars::before {
    translate: 0 calc((var(--bar-gap) + var(--bar)) / 2);
    rotate: 45deg;
  }
  .menu-toggle[aria-expanded="true"] .menu-toggle__bars::after {
    translate: 0 calc((var(--bar-gap) + var(--bar)) / -2);
    rotate: -45deg;
  }

  html[data-js] .menu {
    position: fixed;
    inset-block: 0;
    inset-inline: 0;
    z-index: 0;
    display: grid;
    place-items: center;
    padding: var(--space-8) var(--gutter);
    background: var(--ink);
    overflow-y: auto;
    clip-path: circle(0 at var(--menu-x, 100%) var(--menu-y, 0));
    visibility: hidden;
    transition:
      clip-path var(--menu-dur-out) var(--ease),
      visibility 0s linear var(--menu-dur-out);
  }
  html[data-js] .menu[data-open] {
    clip-path: circle(var(--menu-reach) at var(--menu-x, 100%) var(--menu-y, 0));
    visibility: visible;
    transition: clip-path var(--menu-dur-in) var(--ease);
  }

  html[data-js] .menu__list {
    flex-direction: column;
    gap: var(--space-3);
    text-align: center;
  }
  html[data-js] .menu__item:not(.menu__item--lang) .menu__link {
    font-size: var(--fs-menu);
    font-weight: var(--w-heavy);
    line-height: var(--lh-display);
  }
  html[data-js] .menu__item--lang { margin-block-start: var(--space-5); }
  html[data-js] .menu__item--lang .menu__link {
    min-block-size: var(--tap);
    padding-inline: var(--space-5);
    font-size: var(--fs-base);
  }
}

/* Phones with scripts off: the nav is a row of links that can wrap to a second
   line, so the bar goes back above the hero instead of lying over it. */
@media (max-width: 47.99rem) {
  html:not([data-js]) .masthead--over {
    position: relative;
    background: var(--maroon);
  }
  html:not([data-js]) .hero__text { padding-block-start: var(--space-3); }
}

/* The links rise in one after another once the bubble is most of the way out,
   and drop away at once when it closes. */
@media (max-width: 47.99rem) and (prefers-reduced-motion: no-preference) {
  html[data-js] .menu__item {
    opacity: 0;
    translate: 0 var(--menu-shift);
    transition: opacity var(--menu-dur-out) var(--ease), translate var(--menu-dur-out) var(--ease);
  }
  html[data-js] .menu[data-open] .menu__item {
    opacity: 1;
    translate: 0 0;
    transition: opacity var(--menu-dur-in) var(--ease), translate var(--menu-dur-in) var(--ease);
    transition-delay: var(--menu-delay);
  }
  html[data-js] .menu[data-open] .menu__item:nth-child(2) { transition-delay: calc(var(--menu-delay) + var(--menu-stagger)); }
  html[data-js] .menu[data-open] .menu__item:nth-child(3) { transition-delay: calc(var(--menu-delay) + var(--menu-stagger) * 2); }
  html[data-js] .menu[data-open] .menu__item:nth-child(4) { transition-delay: calc(var(--menu-delay) + var(--menu-stagger) * 3); }
  html[data-js] .menu[data-open] .menu__item:nth-child(5) { transition-delay: calc(var(--menu-delay) + var(--menu-stagger) * 4); }
}

@media (max-width: 47.99rem) and (prefers-reduced-motion: reduce) {
  html[data-js] .menu,
  html[data-js] .menu[data-open] { transition-duration: 0s; transition-delay: 0s; }
}

/* ---------- Hero ---------- */

/* Three layers: the storefront photo (z -2), a veil of the brand maroon with
   transparency (z -1, ::before), then the words. On phones the hero is the
   full height of the screen; the photo fills its lower part and the veil is
   solid behind the words and thins towards the bottom, where the sign shows. */
.hero {
  position: relative;
  isolation: isolate;
  display: grid;
  min-block-size: 100vh;
  min-block-size: var(--hero-min);
  overflow: hidden;
  background: var(--maroon);
  color: var(--milk);
  --focus: var(--milk);
}
.hero::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline: 0;
  z-index: -1;
  background: var(--hero-veil);
}

.hero__text {
  align-self: start;
  padding-block: calc(var(--masthead) + var(--space-3)) calc(var(--tap) + var(--space-7));
}

.hero .button--ghost { background: var(--veil-button); }
.hero .button--ghost:hover { background: var(--maroon); }

/* The scroll cue. Without scripts the dock is always on screen, so it sits above it. */
.hero__scroll {
  position: absolute;
  inset-inline: 0;
  inset-block-end: calc(var(--dock-height) + var(--dock-gap) * 2 + env(safe-area-inset-bottom, 0px));
  display: grid;
  place-items: center;
  inline-size: var(--tap);
  block-size: var(--tap);
  margin-inline: auto;
  border: var(--border) solid var(--milk);
  border-radius: 50%;
  background: var(--veil-button);
  transition: background-color var(--dur-fast);
}
.hero__scroll:hover { background: var(--maroon); }
html[data-js] .hero__scroll { inset-block-end: calc(var(--space-5) + env(safe-area-inset-bottom, 0px)); }

/* Holds its height before site.js fills it, so nothing below shifts. */
.hero__status {
  display: flex;
  align-items: center;
  min-block-size: var(--space-6);
  margin-block-end: var(--space-3);
}

.status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--blush);
  font-size: var(--fs-sm);
  font-weight: var(--w-medium);
  line-height: var(--lh-snug);
}
.status__dot {
  flex: none;
  inline-size: var(--dot);
  block-size: var(--dot);
  border-radius: 50%;
  background: var(--shut);
}
.status[data-state="open"] .status__dot { background: var(--open); }

.hero h1 {
  max-inline-size: var(--measure-hero);
  font-size: var(--fs-hero);
  font-weight: var(--w-heavy);
  line-height: var(--lh-display);
  text-wrap: balance;
}

.hero__lead {
  max-inline-size: var(--measure);
  margin-block-start: var(--space-4);
  color: var(--blush);
  font-size: var(--fs-lg);
  text-wrap: pretty;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-block-start: var(--space-6);
}

.hero__photo {
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: -2;
  block-size: var(--hero-photo);
}
.hero__photo img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  object-position: var(--hero-focus) 100%;
}

/* From 48rem the photo fills the hero and the veil thins sideways, away from the words. */
@media (min-width: 48rem) {
  .hero {
    min-block-size: min(var(--hero-min), var(--hero-max));
    --hero-veil: var(--hero-veil-wide);
    --hero-photo: 100%;
    --hero-focus: var(--hero-focus-wide);
  }
  .hero__text {
    align-self: center;
    padding-block: calc(var(--masthead) + var(--space-6)) calc(var(--tap) + var(--space-8));
  }
  .hero__scroll,
  html[data-js] .hero__scroll { inset-block-end: var(--space-6); }
}

/* ---------- Coffee: the owner's line, bean to cup, and the way to the menu ---------- */

.coffee {
  padding-block: var(--section);
  background: var(--milk);
}

.coffee__head {
  display: grid;
  gap: var(--space-5);
}
.coffee__cta {
  display: grid;
  justify-items: start;
  gap: var(--space-4);
}
.coffee__cta p {
  max-inline-size: var(--measure);
  color: var(--plum);
}

/* On phones a rail: each photo snaps into place and the next one peeks in. */
.steps {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: var(--rail-card);
  gap: var(--space-3);
  margin-block-start: var(--space-6);
  padding-inline: var(--gutter);
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scroll-snap-type: inline mandatory;
  scroll-padding-inline: var(--gutter);
  scrollbar-width: none;
}
.steps::-webkit-scrollbar { display: none; }

.step {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-photo);
  background: var(--ink);
  color: var(--milk);
  scroll-snap-align: start;
}
.step img {
  inline-size: 100%;
  aspect-ratio: var(--ratio-step);
  object-fit: cover;
}
.step::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline: 0;
  background: var(--scrim);
  pointer-events: none;
}
.step__name {
  position: absolute;
  inset-block-end: var(--space-4);
  inset-inline-start: var(--space-5);
  z-index: 1;
  font-size: var(--fs-xl);
  font-weight: var(--w-heavy);
  line-height: var(--lh-snug);
}

@media (min-width: 48rem) {
  .coffee__head {
    grid-template-columns: 1.25fr 1fr;
    align-items: end;
    gap: var(--space-7);
  }

  .steps {
    grid-auto-flow: row;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-4);
    inline-size: min(100% - 2 * var(--gutter), var(--wrap));
    margin-inline: auto;
    margin-block-start: var(--space-7);
    align-items: start;
    padding-inline: 0;
    overflow: visible;
  }
  /* A margin, not a translate: translate belongs to the reveal (see Motion). */
  .step:nth-child(even) { margin-block-start: var(--step-offset); }
}

/* ---------- Hours: the logo redrawn as a 24-hour dial ---------- */

.hours {
  padding-block: var(--section);
  background: var(--sky);
}

.hours__grid {
  display: grid;
  gap: var(--space-6);
}

.hours__intro p {
  max-inline-size: var(--measure);
  margin-block-start: var(--space-3);
  color: var(--plum);
}

/* Noon is at the top (sun), midnight at the bottom (moon). The crimson arc is
   the hours the shop is open; the bead is the time in Riyadh right now. */
.dial {
  display: grid;
  place-items: center;
  inline-size: var(--dial);
  margin-inline: auto;
}
.dial > * { grid-area: 1 / 1; }
.dial__svg { inline-size: 100%; block-size: auto; }

.dial__petal { fill: var(--maroon); }
.dial__plate { fill: var(--milk); }
.dial__track,
.dial__open {
  fill: none;
  stroke-width: var(--dial-stroke);
}
.dial__track { stroke: var(--sky-deep); }
.dial__open {
  stroke: var(--crimson);
  stroke-linecap: round;
}
.dial__rim { fill: var(--ink); }
.dial__coffee { fill: var(--crema); }
.dial__glyph,
.dial__steam {
  fill: none;
  stroke: var(--milk);
  stroke-linecap: round;
  stroke-linejoin: round;
}
.dial__glyph { stroke-width: var(--glyph-stroke); }
.dial__steam { stroke-width: var(--steam-stroke); }
.dial__bead {
  fill: var(--milk);
  stroke: var(--ink);
  stroke-width: var(--now-stroke);
}
.dial__ping {
  fill: none;
  stroke: var(--crimson);
  stroke-width: var(--now-stroke);
  opacity: 0;
}

/* Once site.js knows the time, the steam gives way to the status. */
.dial[data-live] .dial__steam { display: none; }

@media (prefers-reduced-motion: no-preference) {
  .dial[data-revealed] .dial__open { transition: stroke-dasharray var(--dur-dial) var(--ease); }
}

.dial__status {
  display: grid;
  justify-items: center;
  max-inline-size: var(--status-width);
  line-height: var(--lh-snug);
  text-align: center;
}
.dial__status strong { font-size: var(--fs-sm); font-weight: var(--w-heavy); }
.dial__status span { font-size: var(--fs-xs); }

.hours__table {
  inline-size: 100%;
  border-collapse: separate;
  border-spacing: 0;
}
.hours__table th,
.hours__table td {
  padding: var(--space-3) var(--space-4);
  border-block-end: var(--hairline) solid var(--line-on-light);
  line-height: var(--lh-snug);
}
.hours__table th {
  font-weight: var(--w-medium);
  text-align: start;
}
.hours__table td {
  font-variant-numeric: tabular-nums;
  text-align: end;
  white-space: nowrap;
}
.hours__table tr:last-child > * { border-block-end: 0; }

.hours__table tr[data-current] > * {
  border-block-end-color: transparent;
  background: var(--maroon);
  color: var(--milk);
}
.hours__table tr[data-current] > th {
  border-start-start-radius: var(--radius-row);
  border-end-start-radius: var(--radius-row);
}
.hours__table tr[data-current] > td {
  border-start-end-radius: var(--radius-row);
  border-end-end-radius: var(--radius-row);
}

.hours__note {
  margin-block-start: var(--space-3);
  padding-inline: var(--space-4);
  color: var(--plum);
  font-size: var(--fs-xs);
}

@media (min-width: 48rem) {
  .hours__grid {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "intro dial"
      "table dial";
    align-items: center;
    gap: var(--space-6) var(--space-8);
  }
  .hours__intro { grid-area: intro; align-self: end; }
  .hours__week { grid-area: table; align-self: start; }
  .dial { grid-area: dial; --dial: min(28rem, 100%); }
  .dial__status strong { font-size: var(--fs-base); }
  .dial__status span { font-size: var(--fs-sm); }
}

/* ---------- Find us ---------- */

.find {
  padding-block: var(--section);
  background: var(--maroon);
  color: var(--milk);
  --focus: var(--milk);
}

.find__grid {
  display: grid;
  align-items: center;
  gap: var(--space-6);
}

/* The frame clips, so the photo can drift inside it (see Motion). */
.find__photo {
  overflow: hidden;
  border-radius: var(--radius-photo);
}
.find__photo img {
  inline-size: 100%;
  aspect-ratio: var(--ratio-sign);
  object-fit: cover;
}

.find__text p {
  max-inline-size: var(--measure);
  margin-block: var(--space-3) var(--space-5);
  color: var(--blush);
}

@media (min-width: 48rem) {
  .find__grid {
    grid-template-columns: 1.15fr 1fr;
    gap: var(--space-8);
  }
}

/* ---------- Contact ---------- */

.contact {
  padding-block: var(--section);
  background: var(--maroon-deep);
  color: var(--milk);
  --focus: var(--milk);
}

.contact__grid {
  display: grid;
  grid-template-areas: "head" "lines" "social";
  gap: var(--space-5);
}
.contact__grid h2 { grid-area: head; }

.contact__lines {
  display: grid;
  grid-area: lines;
  gap: var(--space-3);
}

.line {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border: var(--border) solid var(--line-on-dark);
  border-radius: var(--radius-row);
  text-decoration: none;
  transition: background-color var(--dur-fast);
}
.line:hover { background: var(--wash-on-dark); }
.line .icon {
  grid-row: span 2;
  inline-size: var(--icon-social);
  block-size: var(--icon-social);
}
.line__label {
  color: var(--blush);
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
}
.line__value {
  font-size: var(--fs-xl);
  font-weight: var(--w-heavy);
  line-height: var(--lh-snug);
}

.social {
  display: flex;
  flex-wrap: wrap;
  grid-area: social;
  gap: var(--space-2);
}
.social a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-block-size: var(--tap);
  padding-inline: var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--wash-on-dark);
  font-size: var(--fs-sm);
  font-weight: var(--w-medium);
  text-decoration: none;
  transition: background-color var(--dur-fast), color var(--dur-fast);
}
.social a:hover { background: var(--milk); color: var(--maroon-deep); }

@media (min-width: 48rem) {
  .contact__grid {
    grid-template-columns: 1fr 1.15fr;
    grid-template-areas:
      "head lines"
      "social lines";
    grid-template-rows: auto 1fr;
    align-items: start;
    gap: var(--space-5) var(--space-8);
  }
}

/* ---------- Footer ---------- */

.site-footer {
  padding-block: var(--space-7) calc(var(--space-7) + var(--dock-height) + var(--dock-gap));
  background: var(--ink);
  color: var(--blush);
  font-size: var(--fs-sm);
  --focus: var(--milk);
}

.site-footer__brand {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}
.site-footer__brand img { inline-size: var(--logo-footer); block-size: var(--logo-footer); }
.site-footer__name {
  color: var(--milk);
  font-size: var(--fs-lg);
  font-weight: var(--w-heavy);
  line-height: var(--lh-snug);
}

.site-footer__base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2) var(--space-5);
  margin-block-start: var(--space-6);
  padding-block-start: var(--space-5);
  border-block-start: var(--hairline) solid var(--line-on-dark);
  font-size: var(--fs-xs);
}
.site-footer__base a { color: var(--milk); text-underline-offset: var(--underline-offset); }

@media (min-width: 48rem) {
  .site-footer { padding-block-end: var(--space-7); }
}

/* ---------- Dock: the three things people come for, in thumb reach ---------- */

.dock { display: none; }

@media (max-width: 47.99rem) {
  .dock {
    position: fixed;
    inset-inline: var(--dock-gap);
    inset-block-end: calc(var(--dock-gap) + env(safe-area-inset-bottom, 0px));
    z-index: var(--z-dock);
    display: block;
    border-radius: var(--radius-pill);
    background: var(--ink);
    color: var(--milk);
    box-shadow: var(--shadow-dock);
    --focus: var(--milk);
    transition: translate var(--dur-dock) var(--ease), visibility 0s;
  }
  /* site.js tucks it away while the hero's own buttons are on screen. */
  .dock[data-tucked] {
    translate: 0 calc(100% + var(--dock-gap) * 2);
    visibility: hidden;
    transition: translate var(--dur-dock) var(--ease), visibility 0s linear var(--dur-dock);
  }

  .dock__list {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    block-size: var(--dock-height);
    padding: var(--space-1);
  }
  .dock__list li { display: grid; }
  .dock a {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    border-radius: var(--radius-pill);
    font-size: var(--fs-sm);
    font-weight: var(--w-medium);
    line-height: var(--lh-snug);
    text-decoration: none;
  }
  .dock li:first-child a { background: var(--milk); color: var(--maroon); }
}

@media (max-width: 47.99rem) and (prefers-reduced-motion: reduce) {
  .dock, .dock[data-tucked] { transition: none; }
}

/* ---------- Motion ----------

   Everything here is decoration: under prefers-reduced-motion none of it runs
   and the page is simply there. Four kinds:

   1. On load (CSS only): the words of the hero arrive in turn and the photo
      eases back from a slight zoom.
   2. Arriving on scroll: site.js marks blocks that start below the fold with
      data-armed and adds data-shown when they scroll into view. A block that
      is already on screen is never armed, so nothing painted is ever hidden,
      and with scripts off nothing is hidden at all. --reveal-i (the place of
      the block among its siblings, set by site.js) staggers neighbours.
   3. Tied to the scroll position (CSS scroll timelines, where supported): the
      hero photo falls behind the scroll and its words lift away, the photos
      ease down from a slight zoom as they enter, the sign photo drifts in its
      frame. Browsers without scroll timelines skip these.
   4. Alive: the open dot and the bead on the dial pulse, the scroll cue bobs. */

@keyframes rise { from { opacity: 0; translate: 0 var(--rise); } }
@keyframes fade { from { opacity: 0; } }
@keyframes settle { from { scale: var(--photo-zoom); } }
@keyframes nudge { 50% { translate: 0 var(--nudge); } }
@keyframes ping {
  from { box-shadow: 0 0 0 0 var(--open-ring); }
  to { box-shadow: 0 0 0 var(--ping) var(--open-ring-end); }
}
@keyframes ping-bead {
  from { opacity: 0.9; scale: 1; }
  to { opacity: 0; scale: var(--ping-scale); }
}
@keyframes drift { to { translate: 0 var(--hero-drift); } }
@keyframes lift { to { opacity: 0; translate: 0 var(--hero-lift); } }
@keyframes develop { from { scale: var(--photo-zoom); } }
@keyframes pan {
  from { translate: 0 calc(var(--pan) * -1); scale: var(--photo-zoom); }
  to { translate: 0 var(--pan); scale: var(--photo-zoom); }
}

@media (prefers-reduced-motion: no-preference) {
  /* 1. On load */
  .hero__status,
  .hero h1,
  .hero__lead,
  .hero__actions { animation: rise var(--dur-rise) var(--ease) both; }
  .hero h1 { animation-delay: var(--stagger); }
  .hero__lead { animation-delay: calc(var(--stagger) * 2); }
  .hero__actions { animation-delay: calc(var(--stagger) * 3); }
  .hero__scroll { animation: fade var(--dur-rise) var(--ease) calc(var(--stagger) * 8) both; }
  .hero__photo img { animation: settle var(--dur-settle) var(--ease) both; }

  /* 2. Arriving on scroll */
  [data-armed] {
    opacity: 0;
    translate: 0 var(--rise);
  }
  [data-armed][data-shown] {
    opacity: 1;
    translate: 0 0;
    transition: opacity var(--dur-reveal) var(--ease), translate var(--dur-reveal) var(--ease);
    transition-delay: calc(var(--reveal-i, 0) * var(--stagger));
  }

  /* The week arrives a row at a time. */
  .hours__week[data-armed] tr {
    opacity: 0;
    translate: 0 var(--rise-row);
  }
  .hours__week[data-shown] tr {
    opacity: 1;
    translate: 0 0;
    transition: opacity var(--dur-reveal) var(--ease), translate var(--dur-reveal) var(--ease);
  }
  .hours__week[data-shown] tr:nth-child(2) { transition-delay: var(--stagger-row); }
  .hours__week[data-shown] tr:nth-child(3) { transition-delay: calc(var(--stagger-row) * 2); }
  .hours__week[data-shown] tr:nth-child(4) { transition-delay: calc(var(--stagger-row) * 3); }
  .hours__week[data-shown] tr:nth-child(5) { transition-delay: calc(var(--stagger-row) * 4); }
  .hours__week[data-shown] tr:nth-child(6) { transition-delay: calc(var(--stagger-row) * 5); }
  .hours__week[data-shown] tr:nth-child(7) { transition-delay: calc(var(--stagger-row) * 6); }

  /* The dial opens like the flower it is: the cup first, then the petals one by one. */
  .dial__petal circle,
  .dial__core {
    transform-box: view-box;
    transform-origin: 50% 50%;
  }
  .dial[data-armed] .dial__petal circle,
  .dial[data-armed] .dial__core { scale: 0; }
  .dial[data-armed] .dial__glyph,
  .dial[data-armed] .dial__status { opacity: 0; }
  .dial[data-shown] .dial__petal circle,
  .dial[data-shown] .dial__core {
    scale: 1;
    transition: scale var(--dur-bloom) var(--ease-spring);
  }
  .dial[data-shown] .dial__petal circle:nth-child(1) { transition-delay: calc(var(--stagger) * 2); }
  .dial[data-shown] .dial__petal circle:nth-child(2) { transition-delay: calc(var(--stagger) * 3); }
  .dial[data-shown] .dial__petal circle:nth-child(3) { transition-delay: calc(var(--stagger) * 4); }
  .dial[data-shown] .dial__petal circle:nth-child(4) { transition-delay: calc(var(--stagger) * 5); }
  .dial[data-shown] .dial__petal circle:nth-child(5) { transition-delay: calc(var(--stagger) * 6); }
  .dial[data-shown] .dial__petal circle:nth-child(6) { transition-delay: calc(var(--stagger) * 7); }
  .dial[data-shown] .dial__glyph,
  .dial[data-shown] .dial__status {
    opacity: 1;
    transition: opacity var(--dur-reveal) var(--ease) calc(var(--stagger) * 9);
  }

  /* 4. Alive */
  .status[data-state="open"] .status__dot { animation: ping var(--dur-ping) var(--ease) infinite; }
  .dial__ping {
    transform-box: fill-box;
    transform-origin: 50% 50%;
    animation: ping-bead var(--dur-ping) var(--ease) infinite;
  }
  .hero__scroll .icon { animation: nudge var(--dur-nudge) ease-in-out infinite; }
}

/* 3. Tied to the scroll position */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .hero__photo img {
      animation: settle var(--dur-settle) var(--ease) both, drift linear both;
      animation-timeline: auto, scroll(root block);
      animation-range: normal, 0 var(--hero-min);
    }
    .hero__text {
      animation: lift linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 calc(var(--hero-min) * 0.7);
    }

    /* On phones the photos sit in a sideways rail, so they follow the swipe. */
    .step img {
      animation: develop linear both;
      animation-timeline: view(inline);
      animation-range: entry 0% cover 50%;
    }
    .find__photo img {
      animation: pan linear both;
      animation-timeline: view(block);
      animation-range: cover;
    }
  }

  @media (prefers-reduced-motion: no-preference) and (min-width: 48rem) {
    .step img { animation-timeline: view(block); }
  }
}

/* ---------- 404 ---------- */

.not-found {
  display: grid;
  align-content: center;
  min-block-size: 70svh;
  padding-block: var(--section);
  background: var(--maroon);
  color: var(--milk);
  --focus: var(--milk);
}
.not-found h1,
.not-found h2 {
  font-size: var(--fs-h2);
  font-weight: var(--w-heavy);
  line-height: var(--lh-display);
}
.not-found p {
  max-inline-size: var(--measure);
  margin-block: var(--space-3) var(--space-5);
  color: var(--blush);
}
.not-found__other {
  margin-block-start: var(--space-7);
  padding-block-start: var(--space-6);
  border-block-start: var(--hairline) solid var(--line-on-dark);
}
