@font-face {
  font-family: 'Tomato Grotesk';
  src: url('../fonts/tomato-grotesk-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Tomato Grotesk';
  src: url('../fonts/tomato-grotesk-500.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Tomato Grotesk';
  src: url('../fonts/tomato-grotesk-700.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Tomato Grotesk';
  src: url('../fonts/tomato-grotesk-900.woff2') format('woff2');
  font-weight: 900; font-style: normal; font-display: swap;
}

@font-face {
  font-family: 'Open Sans Narrow';
  src: url('../fonts/open-sans-narrow-800.woff2') format('woff2');
  font-weight: 800; font-style: normal; font-display: block;
}
@font-face {
  font-family: 'Commit Mono';
  src: url('../fonts/commit-mono-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}

:root {
  --scene-ink: #15321f;
  --scene-ink-70: rgba(21, 50, 31, 0.68);

  --scene-ink-soft: #24583a;
  --glass:    rgba(255, 255, 255, 0.96);
  --glass-72: rgba(255, 255, 255, 0.74);
  --glass-46: rgba(255, 255, 255, 0.48);
  --glass-18: rgba(255, 255, 255, 0.20);
  --veil:     rgba(6, 14, 40, 0.30);

  --paper:    #f4f2ee;
  --paper-0:  rgba(244, 242, 238, 0);
  --ink:      #1e2126;
  --ink-80:   rgba(30, 33, 38, 0.80);
  --ink-55:   rgba(30, 33, 38, 0.55);
  --ink-28:   rgba(30, 33, 38, 0.24);
  --ink-12:   rgba(30, 33, 38, 0.10);
  --blue:     #7eaaff;
  --blue-ink: #17325f;
  --blue-dp:  #2f5fbf;

  --focus:    #3d7dff;
  --spritz:   #ff8a3d;

  /* The fixed drink colours, mirroring the `fixed` block in js/palette.js.
     Field deep and Field pale arrive live from the scene as --ground-a/-b. */
  --drink-deep: #5f265d;
  --drink-lit:  #ffe8bd;

  /* One tile of static grain, reused by every surface that wants texture. It
     is blended into the layers beneath it rather than laid on top, so it never
     sits between the reader and the text. */
  /* The same two grain tiles the stage wears, so every textured surface in the
     page is made of the same material. */
  --noise-fine: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  --noise-coarse: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='420' height='420'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.035' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='420' height='420' filter='url(%23m)'/%3E%3C/svg%3E");
  /* Grain for surfaces that blend it in rather than overlaying it, since
     background-blend-mode has no opacity dial — the strength is baked into the
     rect instead.

     Two things this must not repeat. numOctaves is 1: extra octaves stack
     coarser patterns on top of the base frequency, and that low-frequency
     content is what reads as cloudiness rather than grain. And baseFrequency
     stays under 1: above that the period falls below a pixel and the whole
     thing averages out to flat grey. */
  --noise-dim: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='nd'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='1' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23nd)' opacity='0.55'/%3E%3C/svg%3E");

  --type-shade: #2a1425;

  --shade-rgb: 48 23 41;

  --sun-dx: 0px;
  --sun-dy: 5px;
  --sun-lift-dx: 0px;
  --sun-lift-dy: 11px;
  --sun-lift-blur: 24px;

  --display: 'Tomato Grotesk', 'Helvetica Neue', Helvetica, sans-serif;
  --mono: 'Commit Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --pad: clamp(1.15rem, 2.6vw, 2.4rem);

  --gut: clamp(0.7rem, 2.2vw, 2.4rem);

  --corner-fs: clamp(1.38rem, 1.94vw, 1.9rem);
  --corner-lh: 1.1;
  --inset: clamp(1rem, 2.4vw, 2.6rem);
  --round: clamp(1.6rem, 2.6vw, 2.4rem);

  --ground-a: #8d447a;
  --ground-b: #b0cd9d;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);

  --spring: cubic-bezier(0.34, 1.56, 0.44, 1);
  --ease-io: cubic-bezier(0.65, 0, 0.35, 1);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

@property --glass    { syntax: '<color>'; inherits: true; initial-value: rgba(255,255,255,0.96); }
@property --glass-72 { syntax: '<color>'; inherits: true; initial-value: rgba(255,255,255,0.74); }
@property --glass-46 { syntax: '<color>'; inherits: true; initial-value: rgba(255,255,255,0.48); }
@property --glass-18 { syntax: '<color>'; inherits: true; initial-value: rgba(255,255,255,0.20); }
@property --veil        { syntax: '<color>'; inherits: true; initial-value: rgba(6,14,40,0.30); }
@property --scene-ink   { syntax: '<color>'; inherits: true; initial-value: #15321f; }
@property --scene-ink-soft { syntax: '<color>'; inherits: true; initial-value: #24583a; }
@property --scene-ink-70{ syntax: '<color>'; inherits: true; initial-value: rgba(21,50,31,0.68); }
@property --ground-a { syntax: '<color>'; inherits: true; initial-value: #8d447a; }
@property --ground-b { syntax: '<color>'; inherits: true; initial-value: #b0cd9d; }
@property --gut      { syntax: '<length>'; inherits: true; initial-value: 24px; }
@property --blue     { syntax: '<color>'; inherits: true; initial-value: #7eaaff; }
@property --spritz   { syntax: '<color>'; inherits: true; initial-value: #ff8a3d; }

html {
  transition:
    --glass 1.4s linear, --glass-72 1.4s linear, --glass-46 1.4s linear,
    --glass-18 1.4s linear, --veil 1.4s linear,
    --blue 1.4s linear, --spritz 1.4s linear;
}

html[data-theme="evening"] {
  --glass:    rgba(255, 253, 252, 0.97);
  --glass-72: rgba(252, 248, 255, 0.76);
  --glass-46: rgba(252, 248, 255, 0.50);
  --glass-18: rgba(252, 248, 255, 0.22);
  --veil:     rgba(4, 3, 16, 0.62);
  --blue:     #9db9ff;
  --spritz:   #ff9ec4;
}

body {
  margin: 0;
  min-height: 100svh;
  background: var(--ground-a);
  color: var(--glass);
  font-family: var(--display);
  font-weight: 400;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow: hidden;
}
body.doc-page { overflow: auto; background: var(--paper); color: var(--ink); }

::selection { background: var(--blue); color: var(--blue-ink); }

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

.frame {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  padding: var(--inset);

  padding-top: max(calc(var(--inset) * 1.7), env(safe-area-inset-top));
  padding-bottom: max(calc(var(--inset) * 1.05), env(safe-area-inset-bottom));

  padding-left: max(var(--inset), env(safe-area-inset-left));
  padding-right: max(var(--inset), env(safe-area-inset-right));

  background: linear-gradient(96deg, var(--ground-a) 4%, var(--ground-b) 96%);
}

.stage {
  position: relative;
  flex: 1 1 auto;
  width: 100%;
  min-height: 0;
  border-radius: var(--round);

  corner-shape: squircle;
  overflow: hidden;
  isolation: isolate;
  box-shadow: 0 18px 70px -24px rgba(0, 0, 0, 0.72), 0 0 0 1px rgba(255, 255, 255, 0.07);
}

#gl {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: 0;
  opacity: 0;
  transition: opacity 1.4s var(--ease) 0.1s;
}
body.gl-ready #gl { opacity: 1; }

.sky-fallback {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(58% 52% at 74% 22%, rgba(255, 230, 138, 0.5) 0%, transparent 70%),
    linear-gradient(96deg, #b0cd9d 0%, #8d447a 42%, #5d2d51 100%);
}
body.no-webgl .sky-fallback { z-index: 0; }
body.no-webgl #gl { display: none; }

.no-grain .stage::after { display: none; }

.rings {
  position: absolute;
  inset: 0;
  z-index: 40;
  pointer-events: none;
}

.stage::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 30;
  pointer-events: none;
  opacity: 0.16;
  mix-blend-mode: overlay;
  background-image: var(--noise-fine), var(--noise-coarse);
  background-size: 160px 160px, 420px 420px;
}

.stage::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 29;
  pointer-events: none;
  background: radial-gradient(120% 95% at 50% 42%, transparent 62%, rgba(10, 24, 16, 0.16) 100%);
}

.colophon {
  flex: 0 0 auto;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.7rem;
  padding: 1.5rem 0 0.35rem;
  font-size: clamp(0.86rem, 1.02vw, 1rem);
  letter-spacing: -0.012em;
  color: var(--ink-foot, rgba(255, 255, 255, 0.6));
  transition: color 0.6s linear, opacity 0.6s var(--ease) 0.1s;
}
.colophon a {
  color: inherit;
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size: 0% 1.5px;
  background-position: 0 100%;
  transition: background-size 0.35s var(--ease), opacity 0.3s var(--ease);
  opacity: 0.85;
}
.colophon a:hover { background-size: 100% 1.5px; opacity: 1; }
.colophon a:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: 2px; }
.colophon span { opacity: 0.4; }

.lockup {
  position: absolute;
  inset: 0;
  margin: 0;
  z-index: 15;

  pointer-events: none;

  transform: translate3d(var(--lx, 0px), var(--ly, 0px), 0);
  will-change: transform;
}

.lockup__svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.lk {
  font-family: 'Open Sans Narrow', var(--display);
  font-weight: 800;
}

.lk--sheen { fill: url(#lk-sheen); }

.lk--shade { fill: var(--type-shade); }

.corner {
  margin: 0;
  font-weight: 700;
  font-size: var(--corner-fs);
  letter-spacing: -0.026em;
  line-height: var(--corner-lh);
  text-decoration: none;
  transition: color 0.6s linear;
}
.facts {
  position: absolute;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: calc(var(--corner-fs) * 0.32);
  max-width: 46%;
}
.facts--top {
  top: var(--pad);
  left: var(--pad);
  align-items: flex-start;
}
.facts--bottom {
  bottom: var(--pad);
  right: var(--pad);
  align-items: flex-end;
  text-align: right;
}
.facts--top .corner { color: var(--ink-tl, var(--scene-ink-soft)); }
.facts--bottom .corner { color: var(--ink-br, var(--scene-ink-soft)); }

.facts--bottom .corner:last-child {
  font-weight: 500;
  font-size: 0.94em;
}

a.corner {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size: 0% 1.5px;
  background-position: 100% 100%;
  transition: background-size 0.45s var(--ease);
}
a.corner:hover { background-size: 100% 1.5px; background-position: 0 100%; }
a.corner:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; border-radius: 2px; }

.actions {
  position: absolute;
  z-index: 22;
  left: 50%;

  bottom: calc(var(--pad) + var(--corner-fs) * var(--corner-lh) + 8px);
  translate: -50% 50%;
  display: flex;
  gap: 0.7rem;
}

.masthead {
  position: absolute;
  top: var(--pad);
  right: var(--pad);
  z-index: 21;
  display: flex;
  align-items: center;
  justify-content: flex-end;

  min-height: calc(var(--corner-fs) * var(--corner-lh));
}
.mark {
  display: flex;
  color: var(--ink-mkr, #ffffff);
  text-decoration: none;
  transition: color 0.6s linear;
}
.mark__logo {
  display: block;
  height: clamp(0.82rem, 1.25vw, 1.1rem);
  width: auto;
  aspect-ratio: 724 / 100;

  transition: opacity 0.4s var(--ease);
}
.mark:hover .mark__logo { opacity: 0.7; }
.mark__tag {
  font-family: var(--mono);
  font-size: clamp(0.54rem, 0.68vw, 0.62rem);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--glass-46);
}

.cal { position: relative; display: inline-flex; }

.cal__menu {
  position: absolute;
  bottom: calc(100% + 0.6rem);
  left: 50%;
  translate: -50% 0;
  z-index: 30;
  min-width: 13rem;
  padding: 0.35rem;
  border-radius: 1rem;
  background: #fbfbf8;
  box-shadow:
    0 1px 2px rgb(var(--shade-rgb) / 0.2),
    0 18px 44px -14px rgb(var(--shade-rgb) / 0.55);
  opacity: 0;
  transform: translateY(6px) scale(0.97);
  transform-origin: 50% 100%;
  transition: opacity 0.18s var(--ease), transform 0.26s var(--spring);
}
.cal__menu[hidden] { display: none; }
.cal__menu.is-open { opacity: 1; transform: none; }

.cal__item {
  position: relative;
  z-index: 1;
  display: flex;
  box-sizing: border-box;
  text-decoration: none;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  padding: 0.62rem 0.75rem;
  border: 0;
  border-radius: 0.7rem;
  background: transparent;
  color: var(--scene-ink);
  font-family: var(--display);
  font-weight: 500;
  font-size: 0.94rem;
  letter-spacing: -0.012em;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.18s var(--ease), color 0.18s var(--ease);
}
.cal__item svg { width: 0.92rem; height: 0.92rem; opacity: 0.5; flex: 0 0 auto; }
.cal__item:hover { background: color-mix(in srgb, var(--scene-ink) 9%, transparent); }
.cal__item:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: clamp(0.72rem, 1.2vw, 1.02rem) clamp(1.3rem, 2.1vw, 1.95rem);
  border: 0;
  border-radius: 999px;
  background: #f6f7f3;
  color: var(--scene-ink);
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(0.86rem, 1.08vw, 1rem);
  letter-spacing: -0.015em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    transform 0.42s var(--spring),
    background 0.4s var(--ease),
    box-shadow 0.42s var(--ease);

  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    var(--sun-dx) var(--sun-dy) 5px -1px rgb(var(--shade-rgb) / 0.34),
    var(--sun-lift-dx) var(--sun-lift-dy) var(--sun-lift-blur) -10px rgb(var(--shade-rgb) / 0.7);
}
.btn--primary {
  background: var(--scene-ink);
  color: #f6f7f3;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.16),
    var(--sun-dx) var(--sun-dy) 5px -1px rgb(var(--shade-rgb) / 0.36),
    var(--sun-lift-dx) var(--sun-lift-dy) var(--sun-lift-blur) -10px rgb(var(--shade-rgb) / 0.78);
}
.btn--quiet { background: rgba(255, 255, 255, 0.5); }

@media (hover: hover) {
  .btn:hover {
    transform: translateY(-4px) scale(1.045);
    background: #ffffff;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.8),
      0 3px 6px -1px rgb(var(--shade-rgb) / 0.36),
      0 26px 48px -14px rgb(var(--shade-rgb) / 0.78);
  }

  .btn--primary:hover { background: color-mix(in srgb, var(--scene-ink) 58%, var(--ground-a)); }
}
.btn:active { transform: translateY(-1px) scale(0.985); transition-duration: 0.09s; }
.btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.btn[disabled] { opacity: 0.55; cursor: default; transform: none; }
.btn[data-busy] .btn__label { opacity: 0.6; }

/* Modal buttons are deliberately not restyled: the submit is the same
   .btn--primary as "Add to Calendar", the close the same .btn as "RSVP". */

.link {
  color: inherit;
  text-decoration: none;
  background-image: linear-gradient(var(--blue-dp), var(--blue-dp));
  background-repeat: no-repeat;
  background-size: 100% 1px;
  background-position: 0 100%;
  transition: color 0.35s var(--ease), background-size 0.35s var(--ease);
}
.link:hover { color: var(--blue-dp); background-size: 100% 2px; }

.modal {
  border: 0;
  padding: 0;
  background: transparent;
  max-width: 100%;
  max-height: 100%;
  overflow: visible;

  /* The keyboard shift lives on the card, not here. Any non-none translate
     makes an element the containing block for its position:fixed descendants,
     and that would anchor the debug panel to the dialog instead of the
     viewport. */

  /* The card sits on Field deep, so everything inside it is light on dark.
     These stand in for the --ink-* scale the light document pages use. */
  /* Every colour the modal paints. js/debug-modal.js writes these inline on
     the dialog, so this block is the one place to edit them by hand. The card
     is a two-stop gradient; set --m-card to var(--ground-a) to have it drift
     with the field again. */
  --m-card:        #1d3534;
  --m-card-2:      #2c633c;
  --m-well:        rgba(0, 0, 0, 0.42);
  --m-line:        rgba(126, 222, 120, 0.43);
  --m-ink:         #f6f7f3;
  --m-ink-80:      rgba(246, 247, 243, 0.82);
  --m-ink-55:      #96c383;

  /* Only the selected option needs colours of its own. Unselected chips take
     the same well, text and border as the fields above them. */
  --m-opt-on:      #68b176;
  --m-opt-on-ink:  var(--scene-ink);

  --m-pick:        #69b176;
  --m-pick-ink:    #000000;
  --m-accent:      #bed373;
  --m-warn:        #ffb09b;
  --m-btn:         #ffffff;
  --m-btn-ink:     #1f5137;
  color: var(--m-ink);
}
.modal::backdrop {
  background: rgba(6, 10, 30, 0.5);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  opacity: 0;
  transition: opacity 0.28s var(--ease);
}
.modal.is-open::backdrop { opacity: 1; }

.modal__close {
  position: absolute;
  top: 0.9rem; right: 0.9rem;
  display: grid;
  place-items: center;
  width: 2.1rem; height: 2.1rem;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--m-ink-55);
  cursor: pointer;
  transition: background 0.3s var(--ease), color 0.3s var(--ease);
}
.modal__close svg { width: 1.05rem; height: 1.05rem; }
.modal__close:hover { background: rgba(255, 255, 255, 0.14); color: var(--m-ink); }

.modal__title {
  margin: 0 0 1.35rem;
  font-weight: 900;
  font-size: clamp(1.55rem, 4vw, 2rem);
  line-height: 0.94;
  letter-spacing: -0.04em;
}

/* Both go on the confirmation step: it has its own heading and needs no way
   back into a form that is already sent. */
.modal.is-done .modal__title,
.modal.is-done .modal__close { display: none; }

.modal__card {
  position: relative;
  width: min(30rem, calc(100vw - 2rem));
  max-height: calc(100svh - 2rem - var(--kb, 0px));
  overflow-y: auto;
  padding: clamp(1.25rem, 2.6vw, 1.7rem);
  border-radius: 1.5rem;
  border: 1px solid rgba(255, 255, 255, 0.16);

  /* Same recipe as the page: a two-stop 96deg gradient under grain, at the
     stage's strength but a finer pattern for this size. The grain is a
     background layer rather than an ::after overlay because a scrolling box
     pins its own background to the box, so the texture stays put while the
     content moves. */
  background-color: var(--m-card);
  background-image:
    var(--noise-dim),
    linear-gradient(96deg, var(--m-card) 4%, var(--m-card-2) 96%);
  background-size: 160px 160px, auto;
  background-blend-mode: soft-light, normal;

  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.18),
    0 40px 90px -30px rgba(0, 0, 0, 0.7);
  opacity: 0;
  transform: translateY(14px) scale(0.97);
  translate: 0 calc(var(--kb, 0px) / -2);
  transition: opacity 0.3s var(--ease), transform 0.42s var(--ease),
              translate 0.24s var(--ease);
}
.modal.is-open .modal__card { opacity: 1; transform: none; }

.field { margin: 0 0 1.05rem; }
.field > label:not(.check),
.field--choice > legend {
  display: block;
  padding: 0;
  margin-bottom: 0.3rem;
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--m-ink-55);
}
/* A legend sits tighter to its group than a label does to its input, so it
   gets its own step rather than sharing the label's. */
.field--choice > legend { margin-bottom: 0.55rem; }

.field input[type="text"],
.field input[type="email"] {
  width: 100%;
  padding: 0.62rem 0.8rem;
  border: 1px solid var(--m-line);
  border-radius: 0.7rem;
  background: var(--m-well);
  color: var(--m-ink);
  font-family: var(--display);
  font-size: 0.95rem;
  transition: border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.field input::placeholder { color: rgba(246, 247, 243, 0.42); }
.field input:focus {
  outline: none;
  border-color: var(--m-accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--m-accent) 30%, transparent);
}
.field input[aria-invalid="true"] { border-color: var(--m-warn); }
.field__hint {
  margin: 0.35rem 0 0;
  font-size: 0.78rem;
  color: var(--m-warn);
}
.field__hint:empty { display: none; }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* The three-way answer. A fieldset so the legend labels the group for a screen
   reader, reset to sit flush like every other field. */
.field--choice {
  margin: 0 0 1.05rem;
  padding: 0;
  border: 0;
  min-inline-size: 0;
}

.choice {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.45rem;
}
.choice__opt { position: relative; display: block; cursor: pointer; }
.choice__opt input { position: absolute; opacity: 0; width: 0; height: 0; }

/* Unselected sits on Drink deep, the same surface as the inputs above it.
   Selected lifts to Drink lit — one treatment for all three, so the answers
   read as equal choices rather than a right one and two wrong ones. */
.choice__face {
  display: grid;
  place-items: center;
  min-height: 2.75rem;
  height: 100%;
  padding: 0.5rem 0.4rem;
  border: 1px solid var(--m-line);
  border-radius: 0.85rem;
  background: var(--m-well);
  color: var(--m-ink-80);
  font-family: var(--display);
  font-size: 0.84rem;
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-wrap: balance;
  transition: transform 0.24s var(--ease), border-color 0.24s var(--ease),
              color 0.24s var(--ease), box-shadow 0.24s var(--ease),
              background 0.24s var(--ease);
}
.choice__opt input:checked ~ .choice__face {
  border-color: transparent;
  background: var(--m-opt-on);
  color: var(--m-opt-on-ink);
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    0 12px 24px -12px rgba(0, 0, 0, 0.55);
}
@media (hover: hover) {
  .choice__opt:hover .choice__face {
    border-color: color-mix(in srgb, var(--m-opt-on) 45%, transparent);
    transform: translateY(-1px);
  }
  .choice__opt:hover input:checked ~ .choice__face {
    border-color: transparent;
    transform: translateY(-3px);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.7),
      0 16px 28px -12px rgba(0, 0, 0, 0.6);
  }
}
.choice__opt:active .choice__face { transform: translateY(0) scale(0.975); transition-duration: 0.09s; }
.choice__opt input:focus-visible ~ .choice__face {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
.choice[aria-invalid="true"] .choice__face { border-color: var(--m-warn); }

.field--check { margin-top: 1.3rem; }
.check {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  cursor: pointer;
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--m-ink-80);
}
.check input { position: absolute; opacity: 0; width: 0; height: 0; }
.check__box {
  flex: 0 0 auto;
  position: relative;
  width: 1.15rem; height: 1.15rem;
  margin-top: 0.08rem;
  border: 1px solid var(--m-line);
  border-radius: 0.35rem;
  background: var(--m-well);
  transition: background 0.25s var(--ease), border-color 0.25s var(--ease);
}
.check__box::after {
  content: '';
  position: absolute;
  left: 0.36rem; top: 0.14rem;
  width: 0.3rem; height: 0.58rem;
  border: solid var(--m-pick-ink);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0);
  transition: transform 0.25s var(--ease);
}
.check input:checked ~ .check__box { background: var(--m-pick); border-color: var(--m-pick); }
.check input:checked ~ .check__box::after { transform: rotate(45deg) scale(1); }
.check input:focus-visible ~ .check__box { outline: 2px solid var(--focus); outline-offset: 2px; }
.check input[aria-invalid="true"] ~ .check__box { border-color: var(--m-warn); }

/* The document-page link underline is a dark blue that disappears on Field
   deep, so inside the modal it picks up Drink lit instead. */
.modal .link { background-image: linear-gradient(var(--m-accent), var(--m-accent)); }
.modal .link:hover { color: var(--m-accent); }

.modal__status { margin: 0.9rem 0 0; font-size: 0.85rem; color: var(--m-ink-55); }
.modal__status[data-kind="error"] { color: var(--m-warn); }
.modal__status:empty { display: none; }

.modal__actions {
  display: flex;
  align-items: stretch;
  gap: 0.6rem;
  margin-top: 1.45rem;
}
/* Defaults resolve to exactly what .btn--primary already paints, so the submit
   still matches "Add to Calendar" — the tokens exist so the debug panel can
   repaint it without touching the page buttons. */
.modal .btn--primary { background: var(--m-btn); color: var(--m-btn-ink); }
.modal__actions .btn { padding: 0.7rem 1.2rem; font-size: 0.94rem; }
.modal__actions .btn--primary { flex: 1 1 auto; }

.modal__done { text-align: center; padding: 0.6rem 0 0.2rem; }
.modal__done h3 { margin: 0 0 0.6rem; font-weight: 900; font-size: 1.7rem; letter-spacing: -0.03em; }
.modal__done p { margin: 0 0 1.15rem; color: var(--m-ink-80); font-size: 0.95rem; line-height: 1.5; }

.doc-foot {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 40;
  display: flex;
  justify-content: center;
  padding: 4rem var(--pad) clamp(1.2rem, 3vh, 2rem);
  pointer-events: none;
  background: linear-gradient(to top,
    var(--paper) 0%,
    var(--paper) 42%,
    var(--paper-0) 100%);
}
.doc-foot .btn { pointer-events: auto; }
.doc-page .btn--primary { background: var(--ink); color: var(--paper); }
@media (hover: hover) {
  .doc-page .btn--primary:hover { background: #333940; }
}

.doc {
  position: relative;
  z-index: 10;
  max-width: 44rem;
  margin: 0 auto;
  padding: clamp(3rem, 8vh, 5rem) var(--pad) clamp(9rem, 18vh, 12rem);
  color: var(--ink);
}
.doc h1 { margin: 0 0 0.6rem; font-weight: 900; font-size: clamp(2.2rem, 6vw, 3.4rem); letter-spacing: -0.04em; line-height: 0.95; }
.doc h2 { margin: 2.4rem 0 0.7rem; font-weight: 700; font-size: clamp(1.05rem, 2vw, 1.25rem); letter-spacing: -0.02em; }
.doc p, .doc li { color: var(--ink-80); line-height: 1.65; font-size: 0.98rem; }
.doc p { margin: 0 0 1rem; }
.doc ul { margin: 0 0 1rem; padding-left: 1.2rem; }
.doc li { margin-bottom: 0.4rem; }
.doc__note {
  margin: 2.6rem 0 0;
  padding: 1rem 1.2rem;
  border-left: 2px solid var(--blue-dp);
  background: rgba(30, 33, 38, 0.04);
  border-radius: 0 0.5rem 0.5rem 0;
  font-size: 0.88rem;
}
.doc__back { display: inline-block; margin-top: 2.4rem; }

.tilt-cta {
  position: absolute;
  left: 50%;
  /* Inside the plate, and stated in the same terms as the actions, so the two
     cannot drift apart. As a fixed element measured off the viewport floor it
     had to guess where the buttons were, and landed on them three times. */
  bottom: calc(var(--pad) + 17% + 3.6rem);
  transform: translateX(-50%);
  z-index: 60;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 1.2rem;
  border: 1px solid var(--glass-18);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  color: var(--glass);
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  animation: rise 0.8s var(--ease) 1.6s both;
}
.tilt-cta[hidden] { display: none; }
.tilt-cta__icon {
  width: 0.8rem; height: 1.25rem;
  border: 1px solid var(--blue);
  border-radius: 0.28rem;
  animation: tilt 2.6s var(--ease-io) infinite;
}
@keyframes tilt { 0%, 100% { transform: rotate(-16deg); } 50% { transform: rotate(16deg); } }
@keyframes rise { from { opacity: 0; transform: translate(-50%, 1rem); } to { opacity: 1; transform: translate(-50%, 0); } }

.boot {
  position: absolute;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  pointer-events: none;
  transition: opacity 0.5s var(--ease), visibility 0.5s;
}
.boot.is-done { opacity: 0; visibility: hidden; }
.boot__bar {
  display: block;
  width: clamp(4.5rem, 9vw, 7rem);
  height: 2px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.28);
  overflow: hidden;
}
.boot__bar i {
  display: block;
  height: 100%;
  width: 0%;
  border-radius: inherit;
  background: #ffffff;
  transition: width 0.45s var(--ease);
}

body.is-loading .masthead,
body.is-loading .colophon { opacity: 0; }
.masthead { transition: opacity 0.6s var(--ease) 0.1s; }

/* There is no way to lock orientation from a web page: screen.orientation.lock()
   needs fullscreen and iOS Safari has never supported it. So this asks instead.
   Gated on `pointer: coarse` as well as the height, or a short desktop window
   would get it. */
.rotate {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.1rem;
  padding: 2rem;
  text-align: center;
  background: linear-gradient(96deg, var(--ground-a) 4%, var(--ground-b) 96%);
  color: var(--ink-foot, rgba(255, 255, 255, 0.9));
}
.rotate__mark { margin: 0; }
.rotate__mark svg { width: 2.4rem; height: 2.4rem; display: block; }
.rotate__text {
  margin: 0;
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: -0.02em;
}

@media (orientation: landscape) and (max-height: 560px) and (pointer: coarse) {
  .rotate { display: flex; }
  .frame { visibility: hidden; }
}

.noscript {
  position: relative;
  z-index: 50;
  max-width: 40rem;
  margin: 18vh auto;
  padding: 2rem;
  font-size: 1.05rem;
  line-height: 1.6;
}

.js [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 0.9rem, 0);
  transition:
    opacity 0.9s var(--ease) var(--rd, 0ms),
    transform 1.05s var(--ease) var(--rd, 0ms);
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

@media (max-width: 760px) {
  .mark { color: #ffffff; }
  .mark__logo { height: clamp(1rem, 3.6vw, 1.25rem); }
  .facts { max-width: 64%; }
  .facts--bottom .corner { color: #ffffff; }

  :root {
    --corner-fs: clamp(1.15rem, 4.4vw, 1.55rem);
    --pad: clamp(1.6rem, 4.4vw, 2.4rem);
  }
  .stage { border-radius: clamp(2.2rem, 8vw, 3.2rem); }
}

@media (max-width: 620px) {
  .actions { bottom: calc(var(--pad) + 17%); translate: -50% 0; gap: 0.5rem; }
  .actions .btn { padding: 0.85rem 1.25rem; font-size: 0.95rem; }
}

@media (max-width: 400px) {
  .actions .btn { padding: 0.72rem 0.9rem; font-size: 0.85rem; }
  /* Three answers side by side on the narrowest phones: give the labels a
     little more room so none of them needs a third line. */
  .choice { gap: 0.3rem; }
  .choice__face { padding: 0.45rem 0.22rem; font-size: 0.78rem; }
}

@media (prefers-reduced-motion: reduce) {
  .tilt-cta__icon, .tilt-cta { animation: none !important; }
  .js [data-reveal] { transition-duration: 0.2s; }
  .modal__card, .modal::backdrop { transition-duration: 0.01ms; }
}

.dbg {
  position: fixed;
  top: 1rem; right: 1rem;
  z-index: 120;
  width: 17.5rem;
  padding: 0.9rem;
  border-radius: 0.7rem;
  background: rgba(18, 20, 24, 0.92);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  color: #e8eaec;
  font-family: var(--mono);
  font-size: 0.68rem;
  line-height: 1.4;
  box-shadow: 0 20px 50px -18px rgba(0, 0, 0, 0.7);
}
.dbg[hidden] { display: none; }
/* Lives inside the <dialog>, so it shares the top layer and stays above the
   backdrop. Opposite corner from the palette panel so the two never overlap. */
.dbg--modal {
  /* Must stay a child of the <dialog>: a modal dialog makes everything outside
     it inert, so a panel in the body would paint above the backdrop but pass
     every click through to the dialog, which closes on backdrop clicks. */
  top: 1rem; left: 1rem; right: auto; bottom: auto;
  width: 19rem;
  max-height: calc(100vh - 2rem);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* With the panel up, slide the card out from under it so the two never
   overlap — only where there is room for both; below that the panel just sits
   over the card, still fully usable. */
@media (min-width: 62rem) {
  .modal.is-debug .modal__card { translate: 10.5rem calc(var(--kb, 0px) / -2); }
}

.dbg__sec {
  grid-column: 1 / -1;
  margin-top: 0.5rem;
  padding-top: 0.45rem;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  font-size: 0.58rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.55;
}
.dbg--modal .dbg__grid { grid-template-columns: 1fr 2rem 3.4rem; }
.dbg--modal input[type="range"] { width: 3.4rem; accent-color: #8fb7ff; }
.dbg__head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.7rem; }
.dbg__head strong { font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; }
.dbg__head button {
  border: 0; background: transparent; color: inherit;
  font-size: 1.1rem; line-height: 1; cursor: pointer; padding: 0 0.2rem;
}
.dbg__grid {
  display: grid;
  grid-template-columns: 1fr 2rem 2rem;
  gap: 0.3rem 0.4rem;
  align-items: center;
}
.dbg__col { font-size: 0.58rem; opacity: 0.6; text-align: center; letter-spacing: 0.08em; }
.dbg__grid--one { grid-template-columns: 1fr 2rem; margin-top: 0.55rem; padding-top: 0.55rem; border-top: 1px solid rgba(255,255,255,0.12); }
.dbg label { opacity: 0.85; }
.dbg input[type="color"] {
  width: 2rem; height: 1.4rem; padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 0.25rem; background: transparent; cursor: pointer;
}
.dbg__row { display: grid; grid-template-columns: 3.2rem 1fr; gap: 0.5rem; align-items: center; margin-top: 0.6rem; }
.dbg__row input[type="range"] { width: 100%; accent-color: #8fb7ff; }
.dbg__foot { display: flex; gap: 0.4rem; margin-top: 0.8rem; }
.dbg__foot button {
  flex: 1 1 0;
  padding: 0.42rem;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 0.35rem;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.dbg__foot button:hover { background: rgba(255, 255, 255, 0.1); }
.dbg__hint { margin: 0.6rem 0 0; font-size: 0.58rem; opacity: 0.45; text-align: center; }

/* Ambient display (?ambient, or any page on port 2000): scene and title only —
   no logo, facts, buttons or footer, and a slimmer top/bottom gutter. */
.is-ambient .masthead,
.is-ambient .facts,
.is-ambient .actions,
.is-ambient .tilt-cta,
.is-ambient .boot,
.is-ambient .colophon { display: none; }

.is-ambient .frame {
  padding-top: max(var(--inset), env(safe-area-inset-top));
  padding-bottom: max(var(--inset), env(safe-area-inset-bottom));
}
