/* ============================================================
   kathmandu.ing
   The poster is the content. Paper, air, one easing.

   Four colours — powder blue, burnt sienna, sage, honey — and an ink drawn
   from sienna's dark end, because none of the four can carry small text on
   the others (sienna on blue is 3.47:1). Ink is information, deep sienna is
   time and action, honey and sage are surfaces. Four cuts of Timeless.
   ============================================================ */

@font-face { font-family: "Timeless Serif"; src: url("fonts/TimelessSerif-Regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Timeless Serif"; src: url("fonts/TimelessSerif-RegularItalic.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "Timeless Serif Text"; src: url("fonts/TimelessSerif-TextRegular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Timeless Sans"; src: url("fonts/TimelessSans-SansMedium.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }

:root {
  --paper:  #CBE0EB;   /* powder blue: the page */
  --mist:   #E2EEF4;   /* paper, lifted: mats and quiet surfaces */
  --sienna: #B45B10;   /* burnt sienna: large marks only, 3.47:1 */
  --sage:   #B6C7B6;
  --honey:  #E6C280;
  --ink:    #2A1B12;   /* 12.18:1 on paper, 9.80 on honey, 9.36 on sage */
  --ink2:   #4A423D;   /* 7.20:1 on paper */
  --act:    #8A4209;   /* deep sienna for text and buttons: 5.38:1, and paper on it */
  --edge:   #6A6A69;   /* input borders: 3.97:1 */
  --rule:   #A3AFB5;

  /* Timeless has no Devanagari; रू falls to the system's own face */
  --serif: "Timeless Serif", "Kohinoor Devanagari", "Noto Serif Devanagari", Georgia, serif;
  --text:  "Timeless Serif Text", "Kohinoor Devanagari", "Noto Serif Devanagari", Georgia, serif;
  --sans:  "Timeless Sans", "Kohinoor Devanagari", "Noto Sans Devanagari", "Helvetica Neue", Arial, sans-serif;

  /* one curve for everything: quick to start, long to settle */
  --ease: cubic-bezier(.16, 1, .3, 1);
  --soft: 14px;
  --gutter: 20px;
  color-scheme: light;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: 140px; scrollbar-gutter: stable; }
html, body { margin: 0; }
body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 500;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior-y: none;
}
a { color: inherit; text-underline-offset: 4px; text-decoration-thickness: 1px; }
:focus-visible { outline: 2px solid var(--act); outline-offset: 3px; border-radius: 6px; }
p, h1, h2, h3, ul, figure, dl, dd { margin: 0; }
ul { padding: 0; list-style: none; }
[hidden] { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
/* the add form's trap for bots: off-screen rather than display:none, which
   the cleverer ones skip */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
/* Turnstile's tap-to-check, when it asks for one */
.human:not(:empty) { margin: 8px 0 18px; }

.i { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 52px; padding: 0 24px; border-radius: 999px;
  background: var(--act); color: var(--paper);
  font: 500 16px/20px var(--sans); letter-spacing: .01em;
  text-decoration: none; border: 0; cursor: pointer;
  transition: transform .5s var(--ease), background-color .3s;
}
.btn:active { transform: scale(.97); transition-duration: .12s; }
.btn .i { width: 18px; height: 18px; }
.btn.small { min-height: 44px; padding: 0 18px; font-size: 15px; }
.btn.ghost { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.round {
  display: inline-grid; place-items: center; width: 48px; height: 48px; flex: none;
  border-radius: 50%; border: 0; cursor: pointer;
  background: var(--mist); color: var(--ink);
  transition: transform .5s var(--ease);
}
.round:active { transform: scale(.92); transition-duration: .12s; }
.linkbtn {
  display: inline-flex; align-items: center; min-height: 44px; background: none; border: 0; padding: 0;
  font: 500 15px/20px var(--sans); color: var(--ink); text-decoration: underline; text-underline-offset: 4px; cursor: pointer;
}

/* ---------- the top bar ---------- */
.top {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  height: 56px; padding: 0 var(--gutter);
  background: rgba(203, 224, 235, .78);
  -webkit-backdrop-filter: saturate(1.4) blur(16px); backdrop-filter: saturate(1.4) blur(16px);
  transition: box-shadow .4s var(--ease);
}
.top.scrolled { box-shadow: 0 1px 0 rgba(42, 27, 18, .12); }
.wordmark { font: 400 24px/1 var(--serif); letter-spacing: -.015em; text-decoration: none; }
.wordmark span { color: var(--sienna); }
/* our Instagram: the mark alone on a phone, the word beside it when there's room */
.ig {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px; min-width: 44px; justify-content: center;
  padding: 0 10px; border-radius: 999px;
  font: 500 15px/20px var(--sans); color: var(--ink); text-decoration: none;
  transition: background-color .3s var(--ease);
}
.ig .i { width: 24px; height: 24px; }
.ig span { display: none; }
@media (hover: hover) { .ig:hover { background: rgba(226, 238, 244, .7); } }
/* The way to post an event: a plus beside Instagram, drawn like it. A tap
   opens it into its words (app.js), a second tap goes there. */
.top-end { display: flex; align-items: center; gap: 0; margin-right: -10px; }
.post {
  display: inline-flex; align-items: center; justify-content: center; min-width: 44px; height: 44px; padding: 0 10px;
  border-radius: 999px; color: var(--ink); text-decoration: none;
  font: 500 15px/20px var(--sans); white-space: nowrap;
  transition: background-color .35s var(--ease);
}
.post .i { width: 24px; height: 24px; transition: rotate .7s var(--ease); }
.post span {
  display: inline-block; max-width: 0; margin-left: 0; opacity: 0; overflow: hidden;
  transition: max-width .6s var(--ease), margin-left .6s var(--ease), opacity .25s var(--ease);
}
.post.open { background: rgba(226, 238, 244, .7); }
.post.open .i { rotate: 90deg; }
.post.open span { max-width: 96px; margin-left: 6px; opacity: 1; transition: max-width .6s var(--ease), margin-left .6s var(--ease), opacity .4s var(--ease) .12s; }
@media (hover: hover) { .post:hover { background: rgba(226, 238, 244, .7); } }

/* ---------- the hero ---------- */
.hero { position: relative; overflow: hidden; padding-bottom: 8px; }
/* The hero painting: its sky and ground are moved onto the page's own blue
   by tools/make-hero.py, so it has no edges. Nothing of the scene is ever
   cropped: on a phone the whole picture, full width, with only empty sky
   trimmed off the top (it overhangs the top, hidden, so the parallax never
   opens a gap). Wider, it runs the full width with the empty sky trimmed,
   and the day moves up into the header. The ratios are rows of the picture: it is
   1402 x 1122, the scene starts about row 370, and a phone shows from row 64. */
.hero-art { position: relative; aspect-ratio: 1402 / 1058; line-height: 0; overflow: hidden; }
.hero-art picture { display: block; position: absolute; inset: -6.05% 0 0; }
.hero-art img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 100%; }
.hero-art .layer { will-change: translate; }
/* The day, and the weather: small print, the posters are what matter. It
   belongs to the header: on a phone it hangs below it, set into the
   painting's sky, the weather under the day; wider, it sits in the middle of
   the header on one line, and the painting is all picture. */
.top .today { position: absolute; top: calc(100% + 26px); left: var(--gutter); }
.today { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-height: 60px;
  font: 400 20px/1.1 var(--serif); letter-spacing: -.01em; color: var(--ink); }
.wx { display: inline-flex; align-items: center; gap: 6px; }
/* the drawing has air round it inside its square; pulled left, its edge
   lines up with the date's */
.wx .wx-g { width: 28px; height: 28px; flex: none; margin: -4px 0 -4px -4px; overflow: visible; }
.wx-t { white-space: nowrap; }
.wx-l { font: 500 15px/20px var(--sans); color: var(--ink2); white-space: nowrap; }
/* MET Norway's licence (CC BY 4.0) asks for a credit: it belongs in the
   footer's terms when those are written */

/* ---------- the weather glyph ----------
   Drawn by public/weather.js; the page sets its size. This is only how it
   moves, and it only moves for people who haven't asked for less motion.
   Still, every glyph is complete: nothing here draws, so with motion off it
   is the same picture standing still.

   Slow enough to notice only if you look: the rays take a minute to go
   round, a cloud drifts a unit and a half each way (units of the 48
   square, so about a pixel at this size), rain is three streaks taking
   turns. Sways use a plain ease-in-out: the site's curve starts quick,
   which on a loop that turns back every few seconds reads as a nudge. The
   bolt's flash uses the site's curve, quick to come and long to go, like
   the real thing; var(--ease) is that curve once this sits in styles.css,
   and the fallback is the same curve written out. */
@media (prefers-reduced-motion: no-preference) {
  .wx-g .wx-rays {
    transform-box: fill-box;
    transform-origin: center;
    animation: wx-turn 60s linear infinite;
  }

  .wx-g .wx-cloud { animation: wx-drift 6s ease-in-out infinite alternate; }

  /* each streak slides down its own slant and fades, a third of a turn
     behind the one before; negative delays so they never start in step */
  .wx-g .wx-drops > * { animation: wx-fall 1.1s linear infinite; }
  .wx-g .wx-drops > :nth-child(2) { animation-delay: -.73s; }
  .wx-g .wx-drops > :nth-child(3) { animation-delay: -.37s; }

  .wx-g .wx-flakes > * { animation: wx-settle 3.3s linear infinite; }
  .wx-g .wx-flakes > :nth-child(2n) { animation-delay: -1.1s; }
  .wx-g .wx-flakes > :nth-child(3n) { animation-delay: -2.2s; }

  .wx-g .wx-bolt { animation: wx-flash 5s var(--ease, cubic-bezier(.16, 1, .3, 1)) infinite; }

  /* three lines of haze, each on its own clock so they never line up */
  .wx-g .wx-haze > * { animation: wx-slide 7s ease-in-out infinite alternate; }
  .wx-g .wx-haze > :nth-child(2) { animation-duration: 9s; animation-direction: alternate-reverse; }
  .wx-g .wx-haze > :nth-child(3) { animation-duration: 8s; animation-delay: -4s; }

  @keyframes wx-turn { to { transform: rotate(1turn); } }
  @keyframes wx-drift {
    from { transform: translateX(-1.5px); }
    to { transform: translateX(1.5px); }
  }
  @keyframes wx-fall {
    0% { transform: translate(.6px, -1.8px); opacity: 0; }
    30%, 65% { opacity: 1; }
    100% { transform: translate(-.6px, 1.8px); opacity: 0; }
  }
  @keyframes wx-settle {
    0% { transform: translateY(-1.5px); opacity: 0; }
    25%, 70% { opacity: 1; }
    100% { transform: translateY(2px); opacity: 0; }
  }
  /* honey to near-white and back, once, near the end of each five seconds */
  @keyframes wx-flash {
    0%, 90% { fill: #E6C280; }
    91% { fill: #F4F8FA; }
    100% { fill: #E6C280; }
  }
  @keyframes wx-slide {
    from { transform: translateX(-2px); }
    to { transform: translateX(2px); }
  }
}
@media (prefers-reduced-motion: no-preference) {
  .today { animation: rise 1.1s var(--ease) both .1s; }
  .wx:not([hidden]) { animation: rise .9s var(--ease) both; }
  .hero-art img { animation: settle 2.2s var(--ease) both; }
}
@keyframes settle { from { opacity: 0; scale: 1.04; } }
@keyframes rise { from { opacity: 0; transform: translateY(14px); } }

/* ---------- filters ---------- */
.filters {
  position: sticky; top: 56px; z-index: 15;
  padding: 12px var(--gutter) 10px;
  background: rgba(203, 224, 235, .86);
  -webkit-backdrop-filter: saturate(1.4) blur(16px); backdrop-filter: saturate(1.4) blur(16px);
}
.seg {
  position: relative; display: grid; grid-template-columns: repeat(4, 1fr);
  padding: 4px; border-radius: 999px; background: var(--mist);
}
.seg button {
  position: relative; z-index: 1; min-height: 40px; border: 0; background: none; cursor: pointer;
  font: 500 15px/20px var(--sans); color: var(--ink); border-radius: 999px;
  transition: color .4s var(--ease);
}
.seg button[aria-checked="true"] { color: var(--paper); }
.seg-ink {
  position: absolute; top: 4px; left: 0; height: calc(100% - 8px); width: 0;
  border-radius: 999px; background: var(--ink);
  transition: transform .55s var(--ease), width .55s var(--ease);
}
.chips {
  display: flex; gap: 8px; margin: 10px calc(var(--gutter) * -1) 0; padding: 0 var(--gutter) 2px;
  overflow-x: auto; scrollbar-width: none; scroll-snap-type: x proximity;
}
.chips::-webkit-scrollbar { display: none; }
.chip {
  flex: none; scroll-snap-align: start; min-height: 36px; padding: 0 16px; border-radius: 999px;
  border: 0; background: transparent; box-shadow: inset 0 0 0 1px rgba(42, 27, 18, .35);
  font: 500 14px/20px var(--sans); color: var(--ink); cursor: pointer;
  transition: background-color .35s var(--ease), color .35s var(--ease), box-shadow .35s var(--ease), transform .4s var(--ease);
}
.chip:active { transform: scale(.95); }
.chip[aria-pressed="true"] { background: var(--sage); box-shadow: inset 0 0 0 1px var(--ink); }

/* ---------- phones: the filters fold into the corner ----------
   The masthead belongs to the top of the page and scrolls away with it.
   The filter bar holds the top edge, and a moment after it gets there it
   folds into its own right-hand end: the mist track draws in, the ink
   slides along it carrying the chosen day (the real word, moved, not a
   copy), the kinds lift away and the frosted band clears. What stays is
   one capsule, the chosen day, the chosen kind beside it, a chevron. A tap
   opens the bar again where it is. Nothing in the page's flow changes
   size: what moves is transform and opacity, plus width on two boxes that
   are out of the flow. */
@media (max-width: 719px) {
  .top { position: relative; }
  .top.scrolled { box-shadow: none; }

  /* Only the small capsule is pinned now, so keyboard focus no longer
     needs 140px of clearance (which made Tab inside the stuck bar scroll
     the page back up); what scrolls under the capsule keeps a little. */
  html { scroll-padding-top: 0; }
  .feed * { scroll-margin-top: 72px; }

  .filters {
    top: env(safe-area-inset-top, 0px);
    background: none;
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  /* the frosted band on a layer of its own, so it can fade without the
     blur ever being animated (and without making the bar a containing
     block for the capsule, which is fixed) */
  .filters::before {
    content: ""; position: absolute; inset: 0; z-index: -1;
    background: rgba(203, 224, 235, .86);
    -webkit-backdrop-filter: saturate(1.4) blur(16px); backdrop-filter: saturate(1.4) blur(16px);
    transition: opacity .45s var(--ease) .05s, visibility 0s;
  }
  /* the track, anchored at its right end so it can draw in to the corner */
  .seg { background: none; isolation: isolate; }
  .seg::before {
    content: ""; position: absolute; top: 0; right: 0; bottom: 0; width: 100%; z-index: -1;
    border-radius: 999px; background: var(--mist);
    transition: width .55s var(--ease), box-shadow .55s var(--ease);
  }
  /* opening, the other days appear once the ink has all but passed them */
  .seg button { transition: color .4s var(--ease), opacity .4s var(--ease) .2s, transform .55s var(--ease); }
  .chips { transform-origin: 100% 0; transition: opacity .4s var(--ease) .1s, transform .55s var(--ease); }

  /* The capsule's button: held to the corner exactly over the folded
     track. The ink and the day's own word are drawn by the bar beneath;
     the button carries the words for its name and its size, and draws the
     kind and the chevron. Fixed rather than sticky, so reaching it with
     the keyboard never scrolls the page. */
  .dock {
    position: fixed; top: calc(env(safe-area-inset-top, 0px) + 12px); right: var(--gutter); z-index: 2;
    display: flex; align-items: center; height: 48px; max-width: calc(100vw - 2 * var(--gutter));
    margin: 0; padding: 0 14px 0 4px; border: 0; border-radius: 999px; background: none;
    font: 500 15px/20px var(--sans); color: var(--ink); cursor: pointer;
    visibility: hidden; pointer-events: none;
    transition: visibility 0s .15s;
  }
  .dock::after { content: ""; position: absolute; inset: -4px -6px; }   /* a thumb's worth */
  .dock:focus-visible { border-radius: 999px; }
  .dock-day {
    flex: none; min-width: 64px; height: 40px; padding: 0 16px; border-radius: 999px;
    line-height: 40px; text-align: center; white-space: nowrap; color: transparent;
  }
  .dock-kind {
    min-width: 0; padding-left: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    opacity: 0; transition: opacity .15s var(--ease);
  }
  .dock-chev { width: 16px; height: 16px; margin-left: 8px; stroke-width: 2; opacity: 0; transition: opacity .15s var(--ease); }

  /* ---- folded ---- */
  .filters.docked { pointer-events: none; }
  .filters.docked::before { opacity: 0; visibility: hidden; transition: opacity .3s var(--ease), visibility 0s .3s; }
  .filters.docked .seg button:not([aria-checked="true"]) { opacity: 0; transition: color .4s var(--ease), opacity .15s var(--ease), transform .55s var(--ease); }
  .filters.docked .chips { opacity: 0; transition: opacity .2s var(--ease), transform .55s var(--ease); }
  .filters.docked .dock { visibility: visible; pointer-events: auto; transition: visibility 0s; }
  .filters.docked .dock-kind, .filters.docked .dock-chev { opacity: 1; transition: opacity .4s var(--ease) .2s; }
}

/* the fold itself: the track draws in, the ink and its word travel with it */
@media (max-width: 719px) and (prefers-reduced-motion: no-preference) {
  .filters.docked .seg::before {
    width: var(--dock-w, 100%);
    box-shadow: 0 10px 28px -12px rgba(42, 27, 18, .42), 0 1px 3px rgba(42, 27, 18, .1), 0 0 0 .5px rgba(42, 27, 18, .12);
  }
  .filters.docked .seg-ink { width: var(--dock-ink) !important; transform: translateX(var(--dock-x)) !important; }
  .filters.docked .seg button[aria-checked="true"] { transform: translateX(var(--dock-dx, 0px)); }
  .filters.docked .chips { transform: translateY(-14px) scale(.96); }
}

/* Less motion: nothing travels. The bar fades where it is, and the
   capsule, drawn whole on the button itself, fades in at the corner. */
@media (max-width: 719px) and (prefers-reduced-motion: reduce) {
  .filters::before, .filters .seg, .filters .chips, .dock, .dock-kind, .dock-chev {
    transition: opacity .2s ease, visibility 0s !important;
  }
  .filters.docked .seg { opacity: 0; }
  .filters.docked .seg button:not([aria-checked="true"]) { opacity: 1; }   /* the bar fades as one */
  .dock {
    opacity: 0; background: var(--mist);
    box-shadow: 0 10px 28px -12px rgba(42, 27, 18, .42), 0 1px 3px rgba(42, 27, 18, .1), 0 0 0 .5px rgba(42, 27, 18, .12);
    transition: opacity .2s ease, visibility 0s .2s !important;
  }
  .filters.docked .dock { opacity: 1; transition: opacity .2s ease, visibility 0s !important; }
  .dock-day { color: var(--paper); background: var(--ink); }
}

@media (max-width: 719px) {
  /* the state a page opens in is drawn, not animated (restored part-way down) */
  .filters.dock-still, .filters.dock-still *, .filters.dock-still::before,
  .filters.dock-still *::before, .filters.dock-still *::after { transition: none !important; }

  /* a new choice made from the bar opened mid-board: the board crossfades
     to the top of the new list as one picture, instead of posters flying
     in from far above */
  html.dock-jump.morph .cell, html.dock-jump.morph .card { view-transition-name: none !important; }
}

/* ---------- the feed ---------- */
.feed { padding: 8px var(--gutter) 24px; min-height: 60vh; }
.group { margin-top: 28px; }
.group:first-child { margin-top: 14px; }
.feed > .grid { margin-top: 18px; }
.group-h { font: italic 400 26px/1.1 var(--serif); letter-spacing: -.01em; margin: 0 0 14px; }
.grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px 14px; }

.card { display: block; text-decoration: none; color: inherit; -webkit-touch-callout: none; }
.card .pic { transition: transform .6s var(--ease); }
.card:active .pic { transform: scale(.975); transition-duration: .15s; }
@media (hover: hover) {
  .card:hover .pic img { transform: scale(1.025); }
}

/* the picture: always a 4:5 window, never a cropped poster */
.pic {
  position: relative; aspect-ratio: 4 / 5; border-radius: var(--soft); overflow: hidden;
  background: var(--mist); isolation: isolate;
}
.pic img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain;
  opacity: 0; transform: scale(1.01);
  transition: opacity .8s var(--ease), transform .9s var(--ease);
}
.pic.loaded img { opacity: 1; transform: none; }
/* a poster taller than its window is zoomed to fill it, edge to edge */
.card .pic.tall img { object-fit: cover; }
.pic.plate .art, .pic.plate .art svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.meta { padding: 10px 2px 0; }
.meta .when { font: 500 13px/18px var(--sans); color: var(--act); letter-spacing: .01em; }
.meta .title { font: 400 19px/1.15 var(--serif); letter-spacing: -.01em; margin-top: 3px; text-wrap: pretty; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.meta .where { font: 500 13px/18px var(--sans); color: var(--ink2); margin-top: 5px; overflow-wrap: anywhere; }
.meta .free { color: var(--act); }

/* Rising into place as they scroll into view. Scroll-driven, so the
   compositor runs it and nothing waits on script; where the browser can't do
   it the posters are simply there. Never hidden by default. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .grid > .cell, .grid > .card, .group-h {
      animation: rise-in linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 55%;
    }
  }
  .feed.fresh .grid > .cell { animation: rise .9s var(--ease) both; animation-delay: calc(var(--i, 0) * 70ms); }
}
@keyframes rise-in { from { opacity: 0; transform: translateY(28px) scale(.985); } }

/* loading: quiet tiles that breathe */
/* "Link copied", where there's no share sheet */
.toast {
  position: fixed; left: 50%; bottom: calc(24px + env(safe-area-inset-bottom)); z-index: 60;
  translate: -50% 12px; opacity: 0; pointer-events: none;
  padding: 10px 18px; border-radius: 999px; background: var(--ink); color: var(--paper);
  font: 500 15px/20px var(--sans); max-width: calc(100vw - 40px); overflow-wrap: anywhere;
  transition: opacity .3s var(--ease), translate .5s var(--ease);
}
.toast.on { opacity: 1; translate: -50% 0; }
/* over an open event: near the top, clear of its buttons */
dialog .toast { bottom: auto; top: calc(18px + env(safe-area-inset-top)); translate: -50% -12px; }
dialog .toast.on { translate: -50% 0; }
.actions .round.done { background: var(--ink); color: var(--paper); }

.card.ghost { aspect-ratio: 4 / 5.9; border-radius: var(--soft); background: var(--mist); opacity: 1; transform: none; }
@media (prefers-reduced-motion: no-preference) {
  .card.ghost { animation: breathe 1.6s ease-in-out infinite alternate; }
}
@keyframes breathe { to { opacity: .45; } }

/* empty */
.empty { text-align: center; padding: 28px 8px 8px; }
.empty-art { width: 200px; margin: 0 auto 8px; }
.empty-art svg { display: block; width: 100%; height: auto; }
.empty h2 { font: italic 400 28px/1.1 var(--serif); }
.empty p { font: 400 16px/24px var(--text); margin: 8px auto 20px; max-width: 30ch; }
.empty .row { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.offline { font: 400 15px/22px var(--text); padding: 12px 0; }
.noscript { padding: 20px; font: 400 16px/24px var(--text); }

/* the end of the board: room to finish scrolling, nothing more */
.feed { padding-bottom: calc(56px + env(safe-area-inset-bottom)); }

/* ---------- one event, in a pop-up ----------
   The poster grows out of its card into a card of its own, centred over the
   board, with the rest of the event under it. A phone and a wide screen get
   the same pop-up; on a wide one the poster sits beside the words. */
dialog.sheet {
  padding: 0; border: 0; margin: 0; max-width: none; max-height: none;
  width: 100%; height: 100%; background: transparent; color: var(--ink);
  overflow: hidden;
}
dialog.sheet[open] {
  display: flex; align-items: center; justify-content: center;
  padding: calc(14px + env(safe-area-inset-top)) 12px calc(14px + env(safe-area-inset-bottom));
}
dialog.sheet::backdrop { background: rgba(42, 27, 18, .45); transition: opacity .36s var(--ease); }
dialog.sheet.closing::backdrop { opacity: 0; }
/* a wide screen's page is held still under an open event; a phone's isn't
   locked this way (see app.js: Safari resizes the screen when it is) */
@media (min-width: 1000px) { html.locked { overflow: hidden; } }
/* the poster in flight: fixed, composited, never stretched */
.flyer {
  position: fixed; z-index: 10; margin: 0; pointer-events: none;
  transform-origin: 0 0; will-change: transform;
  object-fit: contain; border-radius: var(--soft); overflow: hidden; background: var(--mist);
}
.flyer svg { display: block; width: 100%; height: 100%; }
.sheet-panel {
  position: relative; width: 100%; max-width: 560px; max-height: 100%;
  background: var(--paper); border-radius: 22px;
  overflow-y: auto; overscroll-behavior: contain;
  box-shadow: 0 30px 80px -24px rgba(42, 27, 18, .55);
}
.sheet-panel:focus, .sheet-panel:focus-visible { outline: none; }
@media (prefers-reduced-motion: no-preference) {
  dialog.sheet[open]::backdrop { animation: fade .45s var(--ease) both; }
}
@keyframes fade { from { opacity: 0; } }
/* the top of the card: what kind of thing it is, and the way out. It stays
   put while the rest scrolls, and is never over the poster. */
.sheet-head {
  position: sticky; top: 0; z-index: 4;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  height: 52px; padding: 0 4px 0 18px; background: var(--paper);
}
.sheet .close { width: 44px; height: 44px; background: transparent; color: var(--ink); }
@media (hover: hover) { .sheet .close:hover { background: var(--mist); } }

/* the opened poster: its box is exactly the poster, whatever its shape, so
   there are never bars round it */
.detail .pic { margin: 0 12px; aspect-ratio: auto; display: flex; justify-content: center; background: none; border-radius: 0; overflow: visible; }
.detail .pic:not(.loaded) { min-height: 240px; }
.detail .pic img { position: relative; inset: auto; width: auto; max-width: 100%; height: auto; max-height: 64vh; object-fit: contain; display: block; border-radius: var(--soft); }
.detail .pic.plate { display: block; aspect-ratio: 4 / 5; background: var(--mist); border-radius: var(--soft); overflow: hidden; }
.d-body { padding: 18px 18px 6px; }
.detail .eyebrow { display: none; }   /* the card's head says it */
.eyebrow { font: 500 13px/16px var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--act); }
.d-title { font: 400 32px/1.04 var(--serif); letter-spacing: -.02em; text-wrap: balance; overflow-wrap: anywhere; }
.rows { margin-top: 20px; border-top: 1px solid var(--rule); }
.row { display: grid; grid-template-columns: 28px 1fr; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--rule); }
.row > .i { margin-top: 2px; color: var(--act); }
.row .main { font: 500 17px/24px var(--sans); overflow-wrap: anywhere; }
.row .main.free { color: var(--act); }
.row .main .hood { font: italic 400 24px/1.1 var(--serif); }
.row .sub { font: 500 14px/20px var(--sans); color: var(--ink2); margin-top: 2px; overflow-wrap: anywhere; }
.row .go { display: inline-flex; align-items: center; gap: 4px; min-height: 40px; font: 500 15px/20px var(--sans); }
.row .go .i { width: 16px; height: 16px; }
.d-body .about { font: 400 18px/28px var(--text); margin-top: 20px; text-wrap: pretty; overflow-wrap: anywhere; }
.by { font: 500 15px/22px var(--sans); margin-top: 16px; }
.note { font: 400 14px/21px var(--text); color: var(--ink2); margin-top: 10px; }

/* what to do next, held at the bottom of the card while it scrolls */
.actions {
  position: sticky; bottom: 0; z-index: 3;
  display: flex; gap: 10px; align-items: center;
  padding: 12px; margin-top: 8px;
  background: var(--paper); box-shadow: 0 -1px 0 var(--rule);
}
.actions .btn { flex: 1; }

/* filter changes: posters that stay glide to their new places */
html.morph .cell { view-transition-name: var(--vt); }
html.morph::view-transition-old(root), html.morph::view-transition-new(root) { animation-duration: .35s; }
html.morph::view-transition-group(*) { animation-timing-function: var(--ease); }

/* Going to "Add your event" and back. The form rises over the board like
   the event sheet does, and the board settles back behind it; leaving the
   form, it drops away and the board comes forward. The new page's own
   stylesheet decides, so each page knows which way it's going. */
@view-transition { navigation: auto; }
@media (prefers-reduced-motion: no-preference) {
  html.page-add::view-transition-old(root),
  html.page-add::view-transition-new(root),
  html.page-home:not(.morph)::view-transition-old(root),
  html.page-home:not(.morph)::view-transition-new(root) { mix-blend-mode: normal; animation-timing-function: cubic-bezier(.32, .72, 0, 1); animation-fill-mode: both; }
  html.page-add::view-transition-old(root) { animation-name: board-back; animation-duration: .6s; }
  html.page-add::view-transition-new(root) { animation-name: form-up; animation-duration: .6s; }
  html.page-home:not(.morph)::view-transition-old(root) { animation-name: form-down; animation-duration: .45s; z-index: 1; }
  html.page-home:not(.morph)::view-transition-new(root) { animation-name: board-forward; animation-duration: .45s; }
  html.page-add::view-transition-group(root), html.page-home:not(.morph)::view-transition-group(root) { animation: none; }
  html.page-add::view-transition, html.page-home:not(.morph)::view-transition { background: var(--ink); }
}
@keyframes form-up { from { transform: translateY(100%); border-radius: 24px 24px 0 0; } }
@keyframes form-down { to { transform: translateY(100%); border-radius: 24px 24px 0 0; } }
@keyframes board-back { to { transform: scale(.94); opacity: .6; border-radius: 24px; } }
@keyframes board-forward { from { transform: scale(.94); opacity: .6; border-radius: 24px; } }

/* ---------- wider screens ---------- */
@media (min-width: 720px) {
  :root { --gutter: 36px; }
  .grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 36px 24px; }
  /* wide: the Valley full-bleed, the headline set into its empty sky */
  .hero { position: relative; }
  .top .today { top: 50%; left: 50%; translate: -50% -50%; flex-direction: row; align-items: center; gap: 16px; min-height: 0; font-size: 19px; white-space: nowrap; }
  /* the whole painting across the screen, from the sun down: only empty
     sky above it is trimmed (its overhang for the parallax included) */
  .hero-art { aspect-ratio: auto; height: min(52vw, 900px); }
  .hero-art img { object-position: 50% 93%; }   /* a little empty ground off the foot, so the sun has sky over it */
  .wx .wx-g { width: 28px; height: 28px; margin-left: 0; }
  .wx-l { font-size: 14px; }
  .ig span { display: inline; }

  .filters { display: flex; align-items: center; gap: 16px; }
  .seg { flex: none; width: 420px; }
  .chips { margin: 0; padding: 0; flex: 1; }
  .meta .title { font-size: 21px; }
  .group-h { font-size: 32px; }
}
@media (min-width: 1000px) {
  .hero { padding: 0 !important; }
  .grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .feed, .filters, .hero, .top { padding-left: max(var(--gutter), calc((100vw - 1280px) / 2)); padding-right: max(var(--gutter), calc((100vw - 1280px) / 2)); }
  /* on a big screen the event opens as a centred page: poster left, words right */
  dialog.sheet[open] { padding: 5vh 4vw; }
  .sheet-panel { max-width: 1100px; height: 100%; border-radius: 24px; }
  .sheet-head { position: absolute; top: 12px; right: 12px; height: auto; padding: 0; background: none; }
  .sheet-head .eyebrow { display: none; }
  /* the page fills the card, so the buttons sit at its foot however short the event */
  #sheet-body { min-height: 100%; display: flex; flex-direction: column; }
  .detail { flex: 1; display: grid; grid-template-columns: 1.05fr 1fr; grid-template-rows: auto auto 1fr; gap: 0 8px; align-items: start; padding: 28px 28px 0; }
  .detail .pic { margin: 0; position: sticky; top: 28px; grid-row: 1 / span 3; }
  .detail .pic img { max-height: calc(90vh - 56px); }
  .d-body { padding: 8px 28px 24px; }
  .detail .eyebrow { display: block; }
  .d-title { font-size: 44px; margin-top: 8px; }
  /* right under the words; held at the card's foot only when they run long */
  .actions { grid-column: 2; grid-row: 2; align-self: start; margin: 0; padding: 4px 28px 28px; box-shadow: none; background: var(--paper); }
}

/* ============================================================
   Add your event
   ============================================================ */
.form-page { max-width: 600px; margin: 0 auto; padding: 0 var(--gutter) 64px; }
.fhead { padding: 4px 0 20px; }
.topbar { display: flex; justify-content: space-between; align-items: center; min-height: 56px; }
.back { font: 500 15px/20px var(--sans); min-height: 44px; display: inline-flex; align-items: center; }
.fhead-art { width: 200px; margin: 10px 0 0; }
.fhead-art svg { display: block; width: 100%; height: auto; }
.fhead h1 { font: 400 40px/1.02 var(--serif); letter-spacing: -.02em; margin: 6px 0 10px; }
.fhead p { font: 400 17px/26px var(--text); }

fieldset { border: 0; margin: 0; padding: 22px 0 24px; min-width: 0; border-top: 1px solid var(--rule); }
legend { float: left; width: 100%; padding: 0; margin: 0; }
legend + * { clear: both; }
.step { display: block; font: 500 12px/16px var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--act); }
.ltitle { display: block; font: italic 400 30px/1.1 var(--serif); margin-top: 4px; }

.field { margin-top: 16px; }
.field > label:not(.check) + input, .field > label + .prefix, .field > label + textarea { margin-top: 6px; }
.field > label:not(.check), .field > .lab { display: block; font: 500 15px/20px var(--sans); color: var(--ink2); }
.hint { font: 400 15px/22px var(--text); color: var(--ink2); margin: 4px 0 8px; text-wrap: balance; }
.opt { color: var(--ink2); }
input[type=text], input[type=url], input[type=tel], input[type=date], input[type=time], textarea {
  display: block; width: 100%; min-height: 54px; padding: 14px 16px;
  border: 1px solid var(--edge); border-radius: 12px;
  background: var(--mist); color: var(--ink);
  font: 500 17px/24px var(--sans); -webkit-appearance: none; appearance: none; margin: 0;
  transition: border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.field > label + input, .field > label + textarea { margin-top: 8px; }
textarea { min-height: 124px; resize: vertical; }
input:focus-visible, textarea:focus-visible { outline: 0; border-color: var(--ink); box-shadow: 0 0 0 3px rgba(138, 66, 9, .35); }
fieldset:disabled input, fieldset:disabled textarea, fieldset:disabled .choice, fieldset:disabled .check, fieldset:disabled .prefix span {
  color: var(--ink); -webkit-text-fill-color: var(--ink); opacity: 1;
}
.count { font: 500 14px/20px var(--sans); color: var(--ink2); text-align: right; margin-top: 6px; font-variant-numeric: tabular-nums; }
.two, .three { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 18px; align-items: end; }
.two { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.three { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr); }
.three input, .two input { min-width: 0; }
input[type=date], input[type=time] { font-size: 16px; padding-left: 12px; padding-right: 10px; }
.two .field, .three .field { margin-top: 0; }
@media (max-width: 460px) { .three { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } .three .field:first-child { grid-column: 1 / -1; } }
.free-check { min-height: 54px; margin: 0; }
fieldset > .check { margin-top: 10px; }
legend.step { margin-bottom: 2px; }
.prefix { display: flex; align-items: stretch; border: 1px solid var(--edge); border-radius: 12px; min-height: 54px; margin-top: 8px; background: var(--mist); overflow: hidden; }
.prefix span { display: flex; align-items: center; padding: 0 0 0 16px; font: 500 17px/24px var(--sans); }
.prefix input { border: 0; border-radius: 0; padding-left: 8px; min-height: 52px; }
.prefix:focus-within { border-color: var(--ink); box-shadow: 0 0 0 3px rgba(138, 66, 9, .35); }
.prefix input:focus-visible { box-shadow: none; }
.prefix:has(input:disabled) { opacity: .55; }

.kinds { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.choice {
  display: inline-flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 16px 0 12px;
  border-radius: 999px; box-shadow: inset 0 0 0 1px rgba(42, 27, 18, .35);
  font: 500 15px/20px var(--sans); cursor: pointer;
  transition: background-color .35s var(--ease), box-shadow .35s var(--ease);
}
.choice:has(input:checked) { background: var(--sage); box-shadow: inset 0 0 0 1px var(--ink); }
.choice:has(:focus-visible) { outline: 2px solid var(--act); outline-offset: 2px; }
input[type=radio], input[type=checkbox] {
  -webkit-appearance: none; appearance: none; width: 20px; height: 20px; margin: 0;
  border: 1.5px solid var(--ink); border-radius: 50%; background: var(--mist);
  display: grid; place-content: center; flex: none;
}
input[type=checkbox] { border-radius: 6px; }
input[type=radio]:checked::before { content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--ink); }
input[type=checkbox]:checked { background: var(--ink); }
input[type=checkbox]:checked::before { content: ""; width: 10px; height: 5px; border-left: 2px solid var(--paper); border-bottom: 2px solid var(--paper); transform: rotate(-45deg) translate(1px, -1px); }
.check { display: flex; align-items: center; gap: 12px; min-height: 44px; font: 500 16px/20px var(--sans); margin-top: 8px; cursor: pointer; }

/* The poster comes first, and big. The space for it is a blank poster taped
   to the page, a little crooked, with a faint layout inside saying what goes
   here and the board's plus saying what to do. Reach for it (hover, or a
   file dragged over) and it straightens, lifts and warms to honey. */
.fhead .lead { font: 400 17px/26px var(--text); color: var(--ink2); margin-top: -2px; max-width: 32ch; }
.form-page:not([data-step="1"]) .fhead .lead { display: none; }
.field > label.drop, .drop {
  position: relative; display: grid; justify-items: center; text-align: center; gap: 4px;
  margin: 0; padding: 22px 0 6px; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.drop-frame {
  position: relative; display: block; width: min(70%, 288px); aspect-ratio: 4 / 5; margin-bottom: 22px;
  border-radius: var(--soft); background: var(--mist); color: rgba(42, 27, 18, .13);
  box-shadow: inset 0 0 0 1.5px rgba(42, 27, 18, .26);
  rotate: -1.6deg;
  transition: rotate .7s var(--ease), scale .6s var(--ease), box-shadow .35s var(--ease), background-color .45s var(--ease), color .45s var(--ease);
}
.drop-ghost { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.drop-tape {
  position: absolute; top: -9px; left: -12px; width: 62px; height: 22px;
  background: rgba(244, 248, 250, .88); box-shadow: inset 0 0 0 1px rgba(42, 27, 18, .07);
  rotate: -28deg;
}
.drop-tape + .drop-tape { left: auto; right: -12px; rotate: 28deg; }
.drop-plus {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%;
  display: grid; place-items: center; width: 64px; height: 64px; border-radius: 50%;
  background: var(--act); color: var(--paper);
  transition: rotate .7s var(--ease), scale .5s var(--ease);
}
.drop-plus .i { width: 28px; height: 28px; stroke-width: 1.8; }
.drop b { font: 400 28px/1.1 var(--serif); letter-spacing: -.01em; color: var(--ink); }
.drop small { display: block; font: 500 14px/20px var(--sans); color: var(--ink2); max-width: 30ch; }
@media (hover: hover) {
  .drop:hover .drop-frame { rotate: 0deg; scale: 1.02; box-shadow: inset 0 0 0 2px var(--act); }
  .drop:hover .drop-plus { rotate: 90deg; }
}
.drop.over .drop-frame { rotate: 0deg; scale: 1.03; background: var(--glow, #F3DDB0); color: rgba(138, 66, 9, .22); box-shadow: inset 0 0 0 2px var(--act); }
.drop.over .drop-plus { rotate: 90deg; scale: 1.06; }
.drop:active .drop-frame { scale: .98; transition-duration: .15s; }
.drop:has(:focus-visible) { outline: 0; }
.drop:has(:focus-visible) .drop-frame { outline: 2px solid var(--act); outline-offset: 4px; }
@media (prefers-reduced-motion: no-preference) {
  .drop-frame { animation: pinned .9s var(--ease) backwards .12s; }
  .drop b, .drop small, .steps { animation: rise .8s var(--ease) backwards .26s; }
}
@keyframes pinned { from { opacity: 0; translate: 0 22px; rotate: -5deg; } }

/* poster, details, on the board: where the host is, and how little is left */
.steps {
  display: flex; justify-content: center; flex-wrap: wrap; gap: 8px 20px;
  margin: 26px 0 0; padding: 18px 0 0; border-top: 1px solid var(--rule); list-style: none;
  font: 500 13px/18px var(--sans); color: var(--ink2);
}
.steps li { display: inline-flex; align-items: center; gap: 8px; }
.steps span {
  display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(42, 27, 18, .35); font-size: 12px; line-height: 1;
}
.steps [aria-current] { color: var(--ink); }
.steps [aria-current] span { background: var(--act); color: var(--paper); box-shadow: none; }
.form-page:not([data-step="1"]) .steps, .scan:not([hidden]) ~ .steps { display: none; }
/* Two steps. First only the poster, the drop space filling the page; once
   it's read, the rest of the form comes up with what the poster said. */
.form-page[data-step="1"] fieldset:not(#s-poster),
.form-page[data-step="1"] .send, .form-page[data-step="1"] .folded { display: none; }
.form-page[data-step="1"] #s-poster { border-top: 0; padding-top: 6px; }
@media (prefers-reduced-motion: no-preference) {
  .form-page.arriving fieldset:not(#s-poster), .form-page.arriving .send {
    animation: rise .8s var(--ease) both; animation-delay: calc(var(--n, 0) * 70ms);
  }
}
/* reading: the poster, large, with a band of light passing down it */
.scan { display: grid; justify-items: center; gap: 16px; margin-top: 10px; min-height: min(62vh, 540px); align-content: center; }
.scan-pic { position: relative; width: min(72%, 320px); aspect-ratio: 4 / 5; border-radius: var(--soft); overflow: hidden; background: var(--mist); }
.scan-pic img { display: block; width: 100%; height: 100%; object-fit: contain; }
.scan-pic::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 45%;
  background: linear-gradient(to bottom, rgba(255, 248, 232, 0), rgba(255, 248, 232, .6) 50%, rgba(255, 248, 232, 0));
  translate: 0 -100%; pointer-events: none;
}
.scan-note { font: 400 17px/24px var(--text); color: var(--act); }
@media (prefers-reduced-motion: no-preference) {
  .scan-pic { animation: rise .7s var(--ease) both; }
  .scan-pic::after { animation: scan 1.7s cubic-bezier(.45, 0, .55, 1) infinite; }
  .scan-note { animation: breathe 1.1s ease-in-out infinite alternate; }
}
@keyframes scan { to { translate: 0 230%; } }
.picked { display: grid; grid-template-columns: 120px 1fr; gap: 16px; align-items: start; margin-top: 10px; }
.picked .thumb { border-radius: 12px; overflow: hidden; background: var(--mist); aspect-ratio: 4 / 5; display: grid; place-items: center; }
.picked .thumb img { display: block; width: 100%; height: 100%; object-fit: contain; }
.picked b { display: block; font: 500 15px/20px var(--sans); overflow-wrap: anywhere; }
.picked small { display: block; font: 400 15px/22px var(--text); color: var(--ink2); margin-top: 4px; }
/* while Claude reads the poster the line under it breathes; then whatever
   it filled in glows honey for a moment, so the host sees what to check */
.picked small[data-state="reading"] { color: var(--act); }
.picked small[data-state="read"] { color: var(--ink); }
@media (prefers-reduced-motion: no-preference) {
  .picked small[data-state="reading"] { animation: breathe 1.1s ease-in-out infinite alternate; }
}
input.read-in, textarea.read-in { animation: read-glow 2.8s var(--ease) both; }
.choice.read-in { animation: read-glow 2.8s var(--ease) both; }
@keyframes read-glow { from { background-color: #F3DDB0; color: transparent; } }
.links { display: flex; gap: 20px; }
.nopost-note { font: 400 15px/22px var(--text); color: var(--ink2); margin-top: 12px; }

.form-page .btn { width: 100%; min-height: 56px; font-size: 17px; }
.form-page .btn[disabled] { background: var(--sage); color: var(--ink); cursor: progress; }
.send { padding-top: 24px; border-top: 1px solid var(--rule); }
.send .small { font: 400 14px/21px var(--text); color: var(--ink2); margin-top: 12px; text-align: center; }
.stack { display: grid; gap: 10px; }

/* the answer, always in the same place */
.resp { background: var(--sage); border-radius: 18px; padding: 18px 18px 14px; margin: 0 0 24px; }
.resp.checking { background: var(--mist); }
.resp:focus { outline: 0; }
@media (prefers-reduced-motion: no-preference) { .resp { animation: rise .6s var(--ease) both; } }
.st-label { font: 500 12px/16px var(--sans); letter-spacing: .1em; text-transform: uppercase; }
.st-head { font: 400 26px/30px var(--serif); letter-spacing: -.01em; margin-top: 6px; }
.st-msg { font: 400 17px/26px var(--text); margin-top: 8px; }
.st-sub { font: 400 15px/22px var(--text); margin-top: 8px; }
.sent { margin: 12px 0 0; padding: 8px 0 8px 14px; border-left: 2px solid var(--ink); }
.sent dt { font: 500 12px/16px var(--sans); letter-spacing: .1em; text-transform: uppercase; }
.sent dd { font: 400 17px/26px var(--text); margin-top: 2px; overflow-wrap: anywhere; }
.progress { height: 3px; border-radius: 3px; background: rgba(42, 27, 18, .12); margin: 14px 0 4px; position: relative; overflow: hidden; }
.progress span { position: absolute; top: 0; left: 0; height: 3px; width: 32%; border-radius: 3px; background: var(--act); animation: slide 1.5s var(--ease) infinite; }
@keyframes slide { from { transform: translateX(-110%); } to { transform: translateX(330%); } }
.proof-label { font: 500 12px/16px var(--sans); letter-spacing: .1em; text-transform: uppercase; margin: 16px 0 8px; }
.proof .card { opacity: 1; transform: none; max-width: 240px; }

.field.flag { padding-left: 13px; border-left: 3px solid var(--sienna); margin-left: -16px; }
.flag-note { display: block; font: 500 15px/20px var(--sans); color: var(--act); margin-top: 8px; }
input[aria-invalid=true], textarea[aria-invalid=true] { border-color: var(--act); border-width: 2px; }
.folded { display: flex; flex-direction: column; gap: 2px; border-top: 1px solid var(--rule); padding: 16px 0 24px; }
.folded p { font: 400 16px/24px var(--text); }
.ref { display: grid; grid-template-columns: 88px 1fr; gap: 14px; background: var(--sage); border-radius: 14px; padding: 12px; margin-top: 18px; }
.ref .thumb { border-radius: 8px; overflow: hidden; }
.ref .thumb img { display: block; width: 100%; }
.ref b { font: 500 15px/20px var(--sans); }

/* accepted */
.done { text-align: center; }
.done:focus { outline: 0; }
.done-art { width: 180px; margin: 8px auto 0; }
.done-art svg { display: block; width: 100%; height: auto; }
.done h1 { font: 400 40px/1.04 var(--serif); letter-spacing: -.02em; margin: 6px 0 10px; }
.done > p { font: 400 17px/26px var(--text); }
.done .card { opacity: 1; transform: none; max-width: 280px; margin: 22px auto 0; text-align: left; }
.after { margin: 24px 0; border-top: 1px solid var(--rule); text-align: left; }
.after div { display: grid; grid-template-columns: 112px 1fr; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--rule); }
.after dt { font: 500 12px/22px var(--sans); letter-spacing: .1em; text-transform: uppercase; }
.after dd { font: 500 15px/22px var(--sans); }
.copied { font: 500 15px/20px var(--sans); text-align: center; min-height: 20px; }
@media (prefers-reduced-motion: no-preference) {
  .done:not([hidden]) > * { animation: rise .9s var(--ease) both; }
  .done:not([hidden]) > :nth-child(2) { animation-delay: .06s; }
  .done:not([hidden]) > :nth-child(3) { animation-delay: .12s; }
  .done:not([hidden]) > :nth-child(4) { animation-delay: .18s; }
  .done:not([hidden]) > :nth-child(5) { animation-delay: .24s; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}
