/*
 * PrestoEvent - design system, mobile first.
 *
 * THREE COLOR LAYERS (see the plan, section 7)
 *   brand   PrestoBiz red   - marketing pages and the PrestoEvent name
 *   system  indigo          - everything a signed-in customer works in
 *   event   customer pick - the public sign-up page (six schemes, phase 5)
 *
 * The body carries .layer-site or .layer-app and that one class re-points
 * --accent. Components use --accent and never name red or indigo directly, so
 * the same button is red on the marketing site and indigo in the app - and
 * inside the app, red is free to mean exactly one thing: an error.
 *
 * Every text color here was checked against its background; the ratios are
 * in the plan's accessibility section. Note --ink-soft rather than the parent
 * brand's #797677, which sits exactly on the AA line.
 */

:root {
  color-scheme: light;

  /* brand layer - sampled from prestobiz.com */
  --red:        #D2103E;   /* 5.41:1 on white - buttons, large text */
  --red-deep:   #A50D32;   /* 7.77:1 - text links, errors */
  --red-tint:   #FCE9EE;

  /* system layer */
  --indigo:     #37418F;   /* 9.07:1 on white, both directions */
  --indigo-deep:#2B3372;
  --indigo-tint:#EBEDF7;

  /* neutrals */
  --ink:        #111214;   /* 18.74:1 */
  --ink-soft:   #4A4849;   /* 9.07:1 - secondary text */
  --muted:      #5F5B5D;
  --line:       #E3E2E3;
  --line-strong:#CFCDCE;
  --ground:     #F6F6F7;
  --surface:    #FFFFFF;

  /* semantic - separate from any accent */
  --ok:         #0F6B47;  --ok-tint:   #E4F3EC;
  --warn:       #8A5A00;  --warn-tint: #FBF1DF;
  --error:      #A50D32;  --error-tint:#FCE9EE;

  --r:      14px;
  --r-sm:   10px;
  --r-pill: 999px;
  --shadow: 0 1px 2px rgba(17,18,20,.05), 0 8px 24px -12px rgba(17,18,20,.18);

  /* 48px is the comfortable touch target; WCAG 2.5.8's minimum is 24. */
  --tap: 48px;

  --font: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

.layer-site { --accent: var(--red);    --accent-deep: var(--red-deep);    --accent-tint: var(--red-tint); }
.layer-app  { --accent: var(--indigo); --accent-deep: var(--indigo-deep); --accent-tint: var(--indigo-tint); }
/* The event layer: the customer's color scheme, one of six (Appearance::THEMES
   holds the same hex values, and tests/logic.php measures their contrast).
   Classic Red is the default - the same red as the brand. --scrim is the wash
   laid over a background image in the scheme's color, which ties any
   background to the scheme and mutes a repeating texture. */
.layer-event, .theme-classic-red { --accent: #D2103E; --accent-deep: #A50D32; --accent-tint: #FCE9EE; --scrim: rgba(210,16,62,.14); }
.theme-ocean    { --accent: #0F5C96; --accent-deep: #0B4570; --accent-tint: #E6F0F8; --scrim: rgba(15,92,150,.14); }
.theme-forest   { --accent: #166B42; --accent-deep: #0F5030; --accent-tint: #E5F2EA; --scrim: rgba(22,107,66,.14); }
.theme-sunset   { --accent: #B85C00; --accent-deep: #8A4500; --accent-tint: #FBEEDF; --scrim: rgba(184,92,0,.14); }
.theme-plum     { --accent: #6B2D5C; --accent-deep: #521F46; --accent-tint: #F4EAF1; --scrim: rgba(107,45,92,.14); }
.theme-charcoal { --accent: #37393D; --accent-deep: #222326; --accent-tint: #EEEEEF; --scrim: rgba(55,57,61,.14); }

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

/* The browser's own [hidden] rule loses to any author display value, so
   .field { display: block } would make el.hidden = true do nothing. */
[hidden] { display: none !important; }

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

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--ground);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent-deep); text-underline-offset: 2px; }
img { max-width: 100%; }

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.wrap {
  width: 100%;
  max-width: 1080px;
  margin: 0 auto;
  padding-inline: 16px;
}

/* ------------------------------------------------------------------ header */

.topbar {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  /* safe area: a notch or dynamic island must not sit on the logo */
  padding-top: env(safe-area-inset-top, 0px);
}
.topbar .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 60px;
}
.brand {
  font-weight: 800;
  font-size: 20px;
  letter-spacing: -.03em;
  color: var(--ink);
  text-decoration: none;
}
/* The logo, not a text wordmark: the established PrestoEvent mark. Its red
   stays the same whichever layer the page is in. Displayed at half its
   300px width, so it is sharp on a 2x phone screen. */
.brand { display: flex; align-items: center; }
.brand img { display: block; height: 24px; width: auto; }
@media (min-width: 560px) { .brand img { height: 30px; } }

.nav { display: flex; align-items: center; gap: 4px; }
.nav a, .nav button {
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-soft);
  text-decoration: none;
  background: none;
  border: 0;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  cursor: pointer;
  min-height: 44px;
}
.nav a:hover, .nav button:hover { color: var(--accent-deep); background: var(--accent-tint); }
.nav form { margin: 0; }
/* On a phone the nav was squeezed until "Sign-ups" broke across two lines.
   Items never wrap inside themselves; on narrow screens they tighten instead. */
.nav a, .nav button { white-space: nowrap; line-height: inherit; }
.brand { flex: none; }
@media (max-width: 420px) {
  .brand img { height: 20px; }
  .nav { gap: 0; }
  .nav a, .nav button { padding: 10px 8px; font-size: 14px; }
}

/* The app header carries a thin accent rule so a signed-in page is never
   mistaken for the marketing site. */
.layer-app .topbar { border-top: 3px solid var(--indigo); }

/* ------------------------------------------------------------------- page */

main { padding-block: 28px 64px; }

h1, h2, h3 { letter-spacing: -.025em; line-height: 1.15; margin: 0 0 12px; text-wrap: balance; }
h1 { font-size: clamp(28px, 7vw, 44px); font-weight: 800; }
h2 { font-size: 22px; font-weight: 800; }
h3 { font-size: 17px; font-weight: 700; }
p  { margin: 0 0 14px; }

/*
 * Spacing utilities. These exist because the Content-Security-Policy has no
 * 'unsafe-inline' for styles, so a style="..." attribute is silently ignored.
 * tests/markup.sh fails if one appears in a view.
 */
.m-0  { margin: 0; }
.mt-s { margin-top: 10px; }
.mt-m { margin-top: 14px; }
.mt-l { margin-top: 22px; }
.mb-0 { margin-bottom: 0; }
.h-page { font-size: 28px; }
.h-small { font-size: 18px; }
/* Turnstile draws its own box; give it the form's rhythm. */
.captcha { margin-top: 14px; min-height: 65px; }

.lede { font-size: 18px; color: var(--ink-soft); max-width: 36em; }
.muted { color: var(--ink-soft); }
.small { font-size: 14px; }

/* ------------------------------------------------------------------- card */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow);
  padding: 22px 18px;
}
@media (min-width: 560px) { .card { padding: 28px 30px; } }

.narrow { max-width: 460px; margin-inline: auto; }

.stack > * + * { margin-top: 18px; }

/* ---------------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: var(--tap);
  padding: 12px 20px;
  border-radius: var(--r);
  border: 1.5px solid transparent;
  font: inherit;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -.01em;
  text-decoration: none;
  cursor: pointer;
  transition: background .15s, border-color .15s, transform .05s;
}
.btn:active { transform: translateY(1px); }
.btn-block { display: flex; width: 100%; }

.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-deep); }

.btn-secondary { background: var(--surface); color: var(--ink); border-color: var(--line-strong); }
.btn-secondary:hover { border-color: var(--accent); color: var(--accent-deep); }

/* Google's own guidance: white button, their mark, "Continue with Google".
   It is the most prominent option on the sign-in page on purpose - on a phone,
   typing a new password is where a free tool loses people. */
.btn-google { background: #fff; color: #1F1F1F; border-color: #747775; font-weight: 600; }
.btn-google:hover { background: #F8F8F8; }
.btn-google svg { width: 20px; height: 20px; flex: none; }

.btn-danger { background: var(--surface); color: var(--error); border-color: var(--line-strong); }
.btn-danger:hover { border-color: var(--error); }

@media (prefers-reduced-motion: reduce) {
  .btn { transition: none; }
  .btn:active { transform: none; }
}

/* ------------------------------------------------------------------ forms */

.field { display: block; }
.field + .field { margin-top: 14px; }
.field label {
  display: block;
  font-size: 14px;
  font-weight: 700;
  color: var(--ink-soft);
  margin-bottom: 6px;
}
.field input {
  display: block;
  width: 100%;
  min-height: var(--tap);
  padding: 11px 14px;
  font: inherit;
  /* Never below 16px: iOS Safari zooms the whole page on focus under that,
     and the layout lurches - the classic sign of an amateur mobile form. */
  font-size: 16px;
  color: var(--ink);
  background: var(--surface);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-sm);
}
.field input:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px var(--accent-tint); }
.field .hint { font-size: 13px; color: var(--ink-soft); margin-top: 6px; }

.divider {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--ink-soft);
  font-size: 13px;
  font-weight: 600;
  margin-block: 22px;
}
.divider::before, .divider::after { content: ""; flex: 1; height: 1px; background: var(--line); }

details.more { margin-top: 18px; }
details.more summary {
  cursor: pointer;
  font-weight: 700;
  color: var(--accent-deep);
  min-height: 44px;
  display: flex;
  align-items: center;
}

/* ---------------------------------------------------------------- notices */

/* Never color alone: every notice carries words, and errors a leading mark. */
.notice {
  border-radius: var(--r-sm);
  padding: 12px 14px;
  font-size: 15px;
  font-weight: 600;
  border: 1px solid transparent;
}
.notice-ok    { background: var(--ok-tint);    color: var(--ok);    border-color: #BFE3D0; }
.notice-error { background: var(--error-tint); color: var(--error); border-color: #F2C5D0; }
.notice-error::before { content: "! "; font-weight: 800; }
.notice-info  { background: var(--indigo-tint); color: var(--indigo-deep); border-color: #CDD2EE; }

/* ------------------------------------------------------------- dashboard */

.empty {
  text-align: center;
  padding: 44px 20px;
}
.empty .mark {
  width: 64px; height: 64px;
  margin: 0 auto 16px;
  border-radius: 18px;
  background: var(--accent-tint);
  color: var(--accent);
  display: grid; place-items: center;
  font-size: 30px; font-weight: 800;
}
.empty p { max-width: 30em; margin-inline: auto; }

.pill {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: var(--accent-tint);
  color: var(--accent-deep);
}

.row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }

.kv { display: grid; gap: 4px 16px; grid-template-columns: 1fr; margin: 0; }
@media (min-width: 560px) { .kv { grid-template-columns: 160px 1fr; } }
.kv dt { font-size: 13px; font-weight: 700; color: var(--ink-soft); }
.kv dd { margin: 0 0 8px; }

/* -------------------------------------------------------------- marketing */

.hero { padding-block: 32px 12px; }
.hero h1 { max-width: 14em; }
.hero .cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; }

.points { display: grid; gap: 14px; margin-top: 34px; grid-template-columns: 1fr; }
@media (min-width: 720px) { .points { grid-template-columns: repeat(3, 1fr); } }
.points .card h3 { margin-bottom: 6px; }
.points .card p { margin: 0; color: var(--ink-soft); font-size: 15px; }

/* ================================================================ editor */

/* Every form control, not only <input>: textareas and dropdowns get the same
   48px target and 16px text, or iOS zooms on them too. */
.field textarea,
.field select {
  display: block;
  width: 100%;
  min-height: var(--tap);
  padding: 11px 14px;
  font: inherit;
  font-size: 16px;
  color: var(--ink);
  background: var(--surface);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-sm);
}
.field textarea { min-height: 110px; resize: vertical; line-height: 1.5; }
.field textarea:focus,
.field select:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px var(--accent-tint); }

/* An error sits under its own field, in words, with a mark - never color alone. */
.field.has-error input,
.field.has-error textarea,
.field.has-error select { border-color: var(--error); }
.field .err {
  color: var(--error);
  font-size: 14px;
  font-weight: 700;
  margin-top: 6px;
}
.field .err::before { content: "! "; }

.pair { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.pair .field + .field { margin-top: 0; }

/* A checkbox you can hit with a thumb: the whole row is the label. */
.check {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: var(--tap);
  margin-top: 14px;
  font-weight: 600;
  cursor: pointer;
}
.check input { width: 22px; height: 22px; accent-color: var(--accent); flex: none; margin: 0; }
/* A checkbox with a note under it: the note lines up with the label text,
   not the box (22px box + 12px gap). */
.check-field { margin-top: 18px; }
.check-field .hint { margin: 4px 0 0 34px; font-size: 14px; color: var(--ink-soft); }

/* ------------------------------------------------------- layout chooser */

.choices { display: grid; gap: 12px; }
.choice {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 16px;
  background: var(--surface);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r);
  cursor: pointer;
}
.choice input { width: 22px; height: 22px; margin: 2px 0 0; accent-color: var(--accent); flex: none; }
.choice:has(input:checked) { border-color: var(--accent); background: var(--accent-tint); }
.choice b { display: block; font-size: 17px; letter-spacing: -.01em; color: var(--ink); }
.choice span { display: block; color: var(--ink-soft); font-size: 15px; }
.choice small { display: block; color: var(--ink-soft); font-size: 13px; margin-top: 4px; }

/* ------------------------------------------------------------ list rows */

.section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
.section-head h2 { margin: 0; }

.rows { display: grid; gap: 10px; }
.rowitem {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: var(--r);
  padding: 6px 6px 6px 16px;
  min-height: 60px;
  scroll-margin-top: 20px;
}
/* The whole card is the tap target for editing. */
.rowmain {
  flex: 1;
  min-width: 0;
  padding-block: 8px;
  color: var(--ink);
  text-decoration: none;
}
.rowmain:hover .rowname { color: var(--accent-deep); }
.rowname { display: block; font-weight: 700; overflow-wrap: anywhere; }
.rowmeta { display: block; font-size: 14px; color: var(--ink-soft); }

.dayhead {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 18px 0 8px;
}
.dayhead:first-child { margin-top: 0; }

.movers { display: flex; gap: 4px; flex: none; }
.movers form { margin: 0; }
.iconbtn {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  font: inherit;
  font-size: 18px;
  font-weight: 800;
  color: var(--ink-soft);
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: var(--r-sm);
  cursor: pointer;
}
.iconbtn:hover { color: var(--accent-deep); border-color: var(--accent); }
.iconbtn:disabled { opacity: .35; cursor: default; }

.btn-small { min-height: 44px; padding: 8px 14px; font-size: 15px; }

.empty-inline {
  border: 1.5px dashed var(--line-strong);
  border-radius: var(--r);
  padding: 18px;
  text-align: center;
  color: var(--ink-soft);
}

/* -------------------------------------------------------------- dashboard */

.eventcard {
  display: block;
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: var(--r);
  padding: 16px 18px;
  color: var(--ink);
  text-decoration: none;
  box-shadow: var(--shadow);
}
.eventcard:hover { border-color: var(--accent); }
.eventcard b { display: block; font-size: 18px; letter-spacing: -.015em; overflow-wrap: anywhere; }
.eventcard .rowmeta { margin-top: 4px; }

.pill-draft { background: var(--warn-tint); color: var(--warn); }
.pill-live   { background: var(--ok-tint); color: var(--ok); }
.pill-closed { background: var(--ground); color: var(--ink-soft); border: 1px solid var(--line-strong); }

/* What stands between a draft and publishing, as a checklist. */
.todo { margin: 0; padding-left: 22px; font-weight: 700; }
.todo li { margin-bottom: 4px; }
.statuscard .row form { margin: 0; }

/* Responses: a slot row that is information, not a link. */
.rowitem-static { padding: 6px 16px; }
.person { padding: 16px 18px; box-shadow: none; }
.person-gone { background: var(--ground); }

/* ------------------------------------------------- sticky sheet actions */

/* The way forward stays on screen: Save sits at the bottom of the viewport on
   a phone rather than at the end of a long form, clear of the home indicator. */
.sheet-actions {
  position: sticky;
  bottom: 0;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 22px -18px -22px;
  padding: 14px 18px calc(14px + env(safe-area-inset-bottom, 0px));
  background: var(--surface);
  border-top: 1px solid var(--line);
  border-radius: 0 0 var(--r) var(--r);
}
@media (min-width: 560px) {
  .sheet-actions { margin: 26px -30px -28px; padding-inline: 30px; }
}
.sheet-actions .btn { flex: 1 1 auto; }

.danger-zone { border-top: 1px solid var(--line); padding-top: 18px; margin-top: 26px; }

.backlink { display: inline-flex; align-items: center; min-height: 44px; font-weight: 700; text-decoration: none; }

/* Autosave status, announced politely and never in red unless it failed. */
.savestate { font-size: 14px; color: var(--ink-soft); min-height: 20px; }
.savestate.failed { color: var(--error); font-weight: 700; }

/* ======================================================= template gallery */

/* A stacked list on a phone, a grid on a desktop - the same card either way.
   The whole card is one link, and one tap target. */
.tpls { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
@media (min-width: 720px) { .tpls { grid-template-columns: repeat(2, 1fr); } }
.tpls li { display: flex; }

.tpl {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: var(--r);
  padding: 18px 18px 16px;
  color: var(--ink);
  text-decoration: none;
  box-shadow: var(--shadow);
}
.tpl:hover { border-color: var(--accent); }
.tpl:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
/* "Build your own": white like the template cards, so it reads as one of the
   choices; the dashed edge is what says it starts empty. */
.tpl-blank { border-style: dashed; border-color: var(--line-strong); }

.tpl-eyebrow {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-soft);
}
.tpl-popular {
  padding: 2px 8px; border-radius: var(--r-pill);
  background: var(--accent-tint); color: var(--accent-deep); letter-spacing: .04em;
}
.tpl-name { font-size: 20px; font-weight: 800; letter-spacing: -.02em; line-height: 1.2; }
.tpl-glimpse { font-size: 14px; font-weight: 700; color: var(--accent-deep); overflow-wrap: anywhere; }
.tpl-points { display: grid; gap: 4px; margin-top: 4px; font-size: 15px; color: var(--ink-soft); }
.tpl-points span { padding-left: 16px; position: relative; }
.tpl-points span::before { content: ""; position: absolute; left: 2px; top: .6em; width: 6px; height: 6px; border-radius: 50%; background: var(--line-strong); }
.tpl-go { margin-top: auto; padding-top: 10px; font-weight: 800; color: var(--accent); }

.tpl-list { margin: 8px 0 0; padding-left: 20px; color: var(--ink-soft); }
.tpl-list li { margin-bottom: 4px; }

/* The preview: the public page's own cards, in the event layer's colors,
   on a ground of their own so it reads as "their screen", not the editor. */
.preview-frame {
  background: var(--ground);
  border: 1.5px solid var(--line);
  border-radius: var(--r);
  padding: 18px 16px;   /* 16: the day headers bleed by exactly this */
}
.preview-frame .slot { cursor: default; }
.h-preview { font-size: 24px; font-weight: 800; letter-spacing: -.025em; line-height: 1.15; margin: 0 0 6px; color: var(--ink); }

/* ========================================================== public page */

/* One readable column: this page is read on a phone first, and on a desktop
   a sign-up sheet wider than this is harder to scan, not easier. */
.event-wrap { max-width: 600px; }
.event-main { padding-block: 20px 40px; }
.event-banner { margin-bottom: 16px; }
.event-banner-end { margin: 16px 0 0; }

.event-head { margin-bottom: 18px; }
.event-head h1 { margin-bottom: 8px; }
.event-who  { font-weight: 700; color: var(--ink-soft); margin: 0 0 2px; }
.event-when { color: var(--ink-soft); margin: 0 0 10px; }
.event-desc { margin: 10px 0 0; }

/* ------------------------------------------------------------ slot cards */

.slots { display: grid; gap: 10px; }

/* The date stays pinned while its slots scroll past - on a long conference
   list it is the only thing telling you which day you are looking at. */
.slot-day {
  position: sticky;
  top: env(safe-area-inset-top, 0px);
  z-index: 2;
  margin: 12px -16px 0;
  padding: 10px 16px;
  background: var(--ground);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.slot-day:first-child { margin-top: 0; }

/* The whole card is the tap target: it IS the checkbox's label. */
.slot {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 64px;
  padding: 14px 14px 14px 16px;
  background: var(--surface);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* The real checkbox stays in the page for keyboards and screen readers;
   only its drawing is replaced by the tick. */
.slot input[type=checkbox] {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
}
.slot:has(input:focus-visible) { outline: 3px solid var(--accent); outline-offset: 2px; }
.slot:has(input:checked) { border-color: var(--accent); border-width: 2px; background: var(--accent-tint); }
.slot:has(input:checked) .slot-name { color: var(--accent-deep); }

.slot-body { flex: 1; min-width: 0; display: grid; gap: 2px; }
.slot-name { font-weight: 800; font-size: 17px; letter-spacing: -.01em; overflow-wrap: anywhere; }
.slot-sub, .slot-count { font-size: 14px; color: var(--ink-soft); }
/* Who is on this slot - only when the organizer turned names on. */
.slot-names { font-size: 14px; font-weight: 700; color: var(--ink); overflow-wrap: anywhere; margin-top: 2px; }

.bar { display: block; height: 5px; border-radius: 3px; background: var(--line); overflow: hidden; margin-top: 4px; }
.bar i { display: block; height: 100%; background: var(--accent); border-radius: 3px; }
/* Width classes rather than style="width:..": the CSP blocks inline styles. */
.bar .w0 { width: 0; }     .bar .w10 { width: 10%; } .bar .w20 { width: 20%; }
.bar .w30 { width: 30%; }  .bar .w40 { width: 40%; } .bar .w50 { width: 50%; }
.bar .w60 { width: 60%; }  .bar .w70 { width: 70%; } .bar .w80 { width: 80%; }
.bar .w90 { width: 90%; }  .bar .w100 { width: 100%; }

.slot-qty { display: flex; align-items: center; gap: 8px; margin-top: 6px; font-size: 14px; font-weight: 700; color: var(--ink-soft); }
.slot-qty select {
  min-height: 40px; padding: 6px 10px; font: inherit; font-size: 16px;
  border: 1.5px solid var(--line-strong); border-radius: var(--r-sm); background: var(--surface);
}

.chip {
  flex: none;
  font-size: 12px;
  font-weight: 800;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  white-space: nowrap;
}
.chip-open { background: var(--ok-tint); color: var(--ok); }
.chip-full, .chip-past { background: var(--sunk, var(--ground)); color: var(--ink-soft); border: 1px solid var(--line-strong); }

.tick {
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 2px solid var(--line-strong);
  display: grid;
  place-items: center;
}
.slot:has(input:checked) .tick { background: var(--accent); border-color: var(--accent); }
.slot:has(input:checked) .tick::after { content: "✓"; color: #fff; font-weight: 800; font-size: 15px; }

/* Full or past: still readable, clearly unavailable - and never by fading.
   Opacity would drop the grey text below AA contrast; a dashed edge, a tinted
   ground and the word "Full" say it without losing legibility. */
.slot-off { cursor: default; background: var(--ground); border-style: dashed; }
.slot-off .slot-name { color: var(--ink-soft); }
.slot-off .tick { display: none; }

/* ----------------------------------------------------- continue bar */

/* The way forward is always on screen - the fix for the worst flaw in the
   sign-up pages this product competes with. Clears the home indicator. */
.slotbar {
  position: sticky;
  bottom: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 16px -16px 0;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
  background: var(--surface);
  border-top: 1px solid var(--line);
  box-shadow: 0 -6px 20px -12px rgba(17,18,20,.25);
}
.slotbar-count { font-size: 15px; font-weight: 700; color: var(--ink-soft); }
.slotbar .btn { min-width: 140px; }

/* ----------------------------------------------------- details step */

.r-label { font-size: 12px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); margin: 0 0 6px; }
.r-meta  { font-size: 14px; color: var(--ink-soft); margin: 0 0 2px; }
.picked  { margin: 0; padding-left: 20px; font-weight: 700; }
.picked li { margin-bottom: 4px; }

fieldset.field { border: 0; padding: 0; margin: 14px 0 0; min-width: 0; }
fieldset.field legend { font-size: 14px; font-weight: 700; color: var(--ink-soft); padding: 0; margin-bottom: 2px; }
.choicegroup .check { margin-top: 4px; }

/* The bot trap: out of sight and out of the tab order. */
.hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

/* ------------------------------------------------- you're signed up */

.done { text-align: center; }
.done-mark {
  width: 64px; height: 64px; margin: 4px auto 14px;
  border-radius: 50%; display: grid; place-items: center;
  background: var(--ok-tint); color: var(--ok); font-size: 32px; font-weight: 800;
}
.done-title { font-size: 28px; margin-bottom: 6px; }

.recap {
  text-align: left;
  margin: 20px 0 16px;
  padding: 16px;
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r);
}
.recap .r-label { font-size: 15px; letter-spacing: 0; text-transform: none; color: var(--ink); }
.claims { list-style: none; margin: 10px 0 0; padding: 0; }
.claims li {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 0; border-top: 1px solid var(--line); font-weight: 700;
}
.claims form { margin: 0; }
.claim-gone { color: var(--ink-soft); font-weight: 500; text-decoration: line-through; }

.linkbtn {
  background: none; border: 0; padding: 10px 4px; min-height: 44px;
  font: inherit; font-size: 14px; font-weight: 700; color: var(--error);
  text-decoration: underline; cursor: pointer;
}

/* The PrestoEvent signature. A neutral band so the brand red never fights
   the organizer's colors; the whole band is one link, per the spec. */
.lockup {
  display: block;
  margin: 24px -18px -22px;
  padding: 18px;
  border-top: 1px solid var(--line);
  border-radius: 0 0 var(--r) var(--r);
  text-decoration: none;
  text-align: center;
  background: var(--surface);
}
@media (min-width: 560px) { .lockup { margin: 28px -30px -28px; } }
.lockup-line { display: block; font-size: 16px; font-weight: 700; color: var(--ink-soft); }
.lockup-line b { color: var(--red); font-weight: 800; }
.lockup-cta { display: inline-block; margin-top: 6px; font-size: 14px; font-weight: 700; color: var(--red-deep); text-decoration: underline; }
.lockup:hover .lockup-cta { color: var(--red); }

.event-foot { padding-block: 18px calc(18px + env(safe-area-inset-bottom, 0px)); font-size: 13px; }
.event-foot .event-wrap { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.event-foot a { color: var(--ink-soft); }
.event-foot b { color: var(--red); }

/* ----------------------------------------------------------------- footer */

.foot {
  border-top: 1px solid var(--line);
  padding-block: 22px calc(22px + env(safe-area-inset-bottom, 0px));
  font-size: 14px;
  color: var(--ink-soft);
}
.foot a { color: var(--ink-soft); }

/* ============================================================ marketing */

/* The hero: words, then the phone. Side by side once there is room. */
.home-hero { display: grid; gap: 28px; align-items: center; padding-block: 24px 8px; }
@media (min-width: 860px) { .home-hero { grid-template-columns: 1.1fr .9fr; gap: 48px; } }
.home-copy h1 { max-width: 13em; }

/* "Online sign-up sheets / for your <word>". Each line is its own block, so
   the break always falls between them, and the rotating word sits in a
   window exactly one line tall. The window is as wide as its widest word
   ("Conference"), so "for your" never shifts as the words change. */
.home-h1 { text-wrap: wrap; }
.h1-line { display: block; }
.rotator {
  display: inline-block;
  height: 1.15em;              /* = the h1's line-height */
  overflow: hidden;
  vertical-align: bottom;
  color: var(--accent);
}
.rotator-list { display: block; animation: rotate-words 12.5s infinite; }
.rotator-list > span { display: block; height: 1.15em; }
/* Hold each word ~2s, slide ~0.5s; the sixth item is the first word again,
   and the jump from it back to 0 is invisible. */
@keyframes rotate-words {
  0%, 16%    { transform: translateY(0); }
  20%, 36%   { transform: translateY(-1.15em); }
  40%, 56%   { transform: translateY(-2.3em); }
  60%, 76%   { transform: translateY(-3.45em); }
  80%, 96%   { transform: translateY(-4.6em); }
  100%       { transform: translateY(-5.75em); }
}
@media (prefers-reduced-motion: reduce) {
  .rotator-list { animation: none; transform: translateY(-4.6em); }   /* "Event" */
}
.home-copy .cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; }

/* A phone, drawn in CSS, holding the real template's page. Clipped at a
   phone's height with a fade, so it reads as "and it keeps going". */
.phone {
  justify-self: center;
  width: min(100%, 340px);
  border: 10px solid #141216;
  border-radius: 38px;
  overflow: hidden;
  box-shadow: 0 24px 60px -24px rgba(17,18,20,.45);
  background: #141216;
}
.phone-screen {
  position: relative;
  max-height: 600px;
  overflow: hidden;
  border-radius: 28px;
  border: 0 !important;
  padding: 12px 10px !important;
  font-size: 15px;
}
.phone-screen::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 90px;
  background: linear-gradient(transparent, rgba(255,255,255,.95));
  pointer-events: none;
}
.phone-screen .slot { min-height: 54px; padding: 10px 12px; }
.phone-screen .slot-name { font-size: 15px; }
.phone-screen .h-preview { font-size: 20px; }

.home-section { margin-top: 48px; }
.home-section > h2 { margin-bottom: 16px; }

.steps { list-style: none; counter-reset: step; margin: 0; padding: 0; display: grid; gap: 14px; }
@media (min-width: 720px) { .steps { grid-template-columns: repeat(3, 1fr); } }
.steps li { counter-increment: step; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 18px; box-shadow: var(--shadow); }
.steps li::before {
  content: counter(step); display: grid; place-items: center; width: 34px; height: 34px; margin-bottom: 10px;
  border-radius: 50%; background: var(--accent-tint); color: var(--accent-deep); font-weight: 800;
}
.steps b { display: block; font-size: 18px; letter-spacing: -.015em; }
.steps span { display: block; color: var(--ink-soft); margin-top: 4px; }

/* Category chips on the gallery: the current one is marked by aria-current,
   drawn filled - in words for a screen reader, in shape for everyone. */
/* The space below the chips is theirs: .tpls resets its own margin, so a
   utility class on the list would be silently undone. */
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 26px; }
.chips a {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px;
  border: 1.5px solid var(--line-strong); border-radius: var(--r-pill);
  color: var(--ink); font-weight: 700; text-decoration: none; background: var(--surface);
}
.chips a:hover { border-color: var(--accent); color: var(--accent-deep); }
.chips a[aria-current="page"] { background: var(--accent); border-color: var(--accent); color: #fff; }

.faq { display: grid; gap: 10px; }
.faq details { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 0 18px; }
.faq summary { cursor: pointer; font-weight: 700; min-height: 52px; display: flex; align-items: center; }
.faq details p { margin: 0 0 16px; color: var(--ink-soft); }

.home-final { margin-top: 48px; text-align: center; }
.home-final .cta { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; }

.foot-grid { display: grid; gap: 22px; }
@media (min-width: 720px) { .foot-grid { grid-template-columns: 1.2fr 1fr 1.4fr; } }
.foot-grid nav { display: grid; gap: 6px; align-content: start; }
.foot-h { font-size: 12px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; margin: 0 0 6px; color: var(--ink-soft); }
.foot-brand { color: var(--ink); text-decoration: none; font-size: 18px; }
.foot-brand b { color: var(--red); }

/* ================================================================= staff */

/* A dark bar, so the console is never mistaken for a customer's pages. */
.layer-admin .topbar { border-top: 0; }
.staffbar { background: #1C1D21; border-bottom: 0; }
.staffbar .nav a, .staffbar .nav button { color: #E4E3E6; }
.staffbar .nav a:hover, .staffbar .nav button:hover { color: #fff; background: rgba(255,255,255,.12); }
.staff-brand { font-weight: 800; font-size: 18px; letter-spacing: -.02em; color: #fff; text-decoration: none; }
.staff-brand span {
  margin-left: 6px; padding: 2px 8px; border-radius: var(--r-pill);
  background: #FFD27A; color: #1C1D21; font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
}

/* "Viewing as ..." - on every page of every layer while staff view as a
   customer. Amber on near-black: unlike any color a page or scheme uses, so
   it cannot blend into the page beneath. Sticky, and never dismissable. */
.viewing {
  position: sticky;
  top: 0;
  z-index: 50;
  background: #1C1D21;
  color: #FFD27A;              /* 12.9:1 on #1C1D21 */
  border-bottom: 3px solid #FFD27A;
  padding-top: env(safe-area-inset-top, 0px);
}
.viewing-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 14px; padding-block: 8px; }
.viewing b { color: #fff; }
.viewing-meta { display: block; font-size: 14px; }
.viewing form { margin: 0; }
.viewing-end { background: #FFD27A; color: #1C1D21; }
.viewing-end:hover { background: #fff; }

.auditlog { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.auditlog li { display: grid; grid-template-columns: 1fr; gap: 2px; padding: 10px 14px; background: var(--surface); font-size: 15px; }
@media (min-width: 640px) { .auditlog li { grid-template-columns: 120px 1fr; gap: 14px; } }
.audit-when { font-size: 13px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.audit-detail { display: block; font-size: 13px; color: var(--ink-soft); overflow-wrap: anywhere; }
/* Changes and failures stand out in words AND a mark, never color alone. */
.audit-write, .audit-write_blocked, .audit-signin_failed,
.audit-suspend, .audit-close { background: var(--warn-tint) !important; }
.audit-write b::before, .audit-write_blocked b::before, .audit-signin_failed b::before,
.audit-suspend b::before, .audit-close b::before { content: "! "; color: var(--warn); }

/* A stopped account says so at the top of its page, in words and an edge. */
.statuscard-admin.is-stopped { border-left: 5px solid var(--error); }

/* ============================================================ appearance */

/* Screen-reader text: present for assistive technology, invisible on screen. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------------------------------------------------- the background --

   The generated backgrounds.css gives each background --bg (its average
   color) and --bg-img. The average color paints first, so on a slow
   connection the page has its final look before the image arrives and never
   flashes white.

   On the page, the image lives on a FIXED layer behind everything rather than
   on <body> itself: a cover image on a long page would be stretched to the
   page's full height, and background-attachment: fixed is ignored by iOS. */
body.has-bg { background: var(--bg, var(--ground)); }
body.has-bg::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
}
body.has-bg::before,
.preview-frame.has-bg {
  background-color: var(--bg);
  background-image: linear-gradient(var(--scrim), var(--scrim)), var(--bg-img, none);
  background-size: auto, cover;
  background-position: center;
  background-repeat: no-repeat;
}
/* Patterns repeat at their own size - a few KB fills a 4K screen. */
body.bg-kind-tile::before,
.preview-frame.bg-kind-tile { background-size: auto, auto; background-repeat: no-repeat, repeat; background-position: 0 0; }
/* A solid color is exactly the color chosen: no wash over it. */
body.bg-kind-solid::before,
.preview-frame.bg-kind-solid { background-image: none; }

/* ------------------------------------------------------ the header band */

/* Drawn in the scheme; white text on every one of the six passes AA, and the
   gradient only runs darker. The logo sits on a white tile, so a crest in any
   colors reads on any scheme. */
.event-band {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 60px;
  padding: 12px 16px;
  background: linear-gradient(135deg, var(--accent) 0%, var(--accent-deep) 100%);
  color: #fff;
}
/* The picture and the band are one block: photo on top, band beneath it. */
.event-hero {
  margin-bottom: 14px;
  border-radius: var(--r);
  overflow: hidden;
  box-shadow: var(--shadow);
  background: var(--accent-deep);
}
/* 2:1, the shape every library picture was cut to - reserved before the image
   loads, so the page does not jump when it arrives on a slow connection. */
.event-pic { display: block; width: 100%; height: auto; aspect-ratio: 2 / 1; object-fit: cover; }
/* With a picture and nothing to say, the band shrinks to a stripe of color. */
.event-hero.has-pic .event-band:not(:has(> *)) { min-height: 8px; padding: 0; }
.event-band-name { font-weight: 800; font-size: 17px; letter-spacing: -.01em; line-height: 1.25; overflow-wrap: anywhere; }
.event-logo {
  flex: none;
  display: grid;
  place-items: center;
  padding: 6px;
  border-radius: var(--r-sm);
  background: rgba(255,255,255,.95);
}
/* Around 120px on a phone and 240px wide on a desktop - the plan's 325x211
   would take half a phone screen before the first slot. */
.event-logo img { display: block; width: auto; height: auto; max-width: 120px; max-height: 78px; }
@media (min-width: 560px) { .event-logo img { max-width: 240px; max-height: 156px; } }

/* ----------------------------------------------------------- the sheet */

/* Everything people read sits on white, whatever is behind it - so no
   background choice can cost the page its measured contrast. The day headers
   and the Continue bar bleed to the sheet's edges, exactly 16px. */
.event-sheet {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow);
  padding: 18px 16px 16px;
}
.event-sheet .slot-day { background: var(--surface); }
.event-sheet .slotbar { margin-bottom: -16px; border-radius: 0 0 var(--r) var(--r); }
.event-contact { margin: 10px 0 0; font-weight: 700; }
.done-contact { margin: 0 0 16px; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--r); font-weight: 700; }

/* Anything that would otherwise sit straight on the background gets a
   surface of its own. */
.layer-event .backlink { background: var(--surface); border-radius: var(--r-pill); padding-inline: 16px; box-shadow: var(--shadow); }
.layer-event .event-foot { background: var(--surface); border-top: 1px solid var(--line); }

/* ---------------------------------------------------- appearance sheet */

.pickset { border: 0; padding: 0; margin: 0; min-width: 0; }
.pickset legend { padding: 0; margin-bottom: 6px; }
.pickset .err { color: var(--error); font-size: 14px; font-weight: 700; margin-top: 8px; }
.pickset .err::before { content: "! "; }

/* The real radio stays in the page for keyboards and screen readers; only
   its drawing is replaced. */
.swatch input, .bgpick input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.swatch:has(input:focus-visible),
.bgpick:has(input:focus-visible) { outline: 3px solid var(--indigo); outline-offset: 2px; }

/* A scheme swatch. Its own theme-* class re-points --accent inside it only,
   so the editor around it stays indigo. */
.swatches { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
@media (min-width: 560px) { .swatches { grid-template-columns: repeat(3, 1fr); } }
.swatch {
  position: relative;
  display: block;
  overflow: hidden;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r);
  background: var(--surface);
  cursor: pointer;
}
.swatch-band { display: block; height: 44px; background: linear-gradient(135deg, var(--accent), var(--accent-deep)); }
.swatch-name { display: flex; align-items: center; gap: 10px; min-height: 48px; padding: 0 12px; font-weight: 700; }
/* Selected is a filled dot as well as a ring - never color alone. */
.swatch-name::before {
  content: ""; flex: none; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--line-strong); background: var(--surface);
}
.swatch:has(input:checked) { border: 2px solid var(--ink); }
.swatch:has(input:checked) .swatch-name::before { border-color: var(--ink); background: var(--ink); box-shadow: inset 0 0 0 3px var(--surface); }

.pick-group {
  font-size: 13px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-soft); margin: 16px 0 8px;
}
/* 64px thumbnails: comfortably over the 48px tap target. */
.bgpicks { display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: 8px; }
.bgpick { position: relative; display: block; cursor: pointer; border-radius: var(--r-sm); }
.bgthumb { display: block; aspect-ratio: 1; border-radius: var(--r-sm); border: 1px solid var(--line-strong); }
.bgpick:has(input:checked) .bgthumb { box-shadow: 0 0 0 2px var(--surface), 0 0 0 5px var(--indigo); }
.bgpick:has(input:checked)::after {
  content: "\2713"; position: absolute; top: 4px; right: 4px;
  width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center;
  background: var(--indigo); color: #fff; font-size: 13px; font-weight: 800;
}

.logo-now {
  display: flex;
  padding: 14px;
  border-radius: var(--r);
  background: linear-gradient(135deg, var(--accent), var(--accent-deep));
}

/* ------------------------------- the look, as a picture, in the app */

/* A miniature page: the background, with a band of the scheme across the top.
   Used by the editor's Appearance card and the template gallery. */
.look-art, .tpl-art { position: relative; display: block; overflow: hidden; background: var(--ground); }
.look-art > span, .tpl-art > span {
  position: absolute; top: 0; left: 0; right: 0; height: 34%;
  background: linear-gradient(135deg, var(--accent), var(--accent-deep));
}
.look-art { flex: none; width: 72px; height: 72px; border-radius: var(--r-sm); border: 1px solid var(--line); }
.look-art img { display: block; width: 100%; height: 100%; object-fit: cover; }
.look-art.has-pic > span { top: auto; bottom: 0; height: 12px; }

.looklink { display: flex; align-items: center; gap: 14px; padding: 14px; color: var(--ink); text-decoration: none; }
.looklink:hover { border-color: var(--indigo); }
.look-text { flex: 1; min-width: 0; display: grid; gap: 2px; }
.look-text b { font-size: 18px; letter-spacing: -.015em; }
.look-go { flex: none; font-size: 20px; font-weight: 800; color: var(--indigo); }

.tpl-art { height: 84px; margin: -18px -18px 8px; border-radius: var(--r) var(--r) 0 0; border-bottom: 1px solid var(--line); }

/* The template preview sits on the template's own background. */
.preview-frame .event-hero { margin-bottom: 12px; }

/* Header pictures in the picker: the same 2:1 as on the page. */
.picpicks { display: grid; grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); gap: 8px; }
.picpicks .bgthumb { aspect-ratio: 2 / 1; }
.picpicks img { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: var(--r-sm); }
.bgthumb-none { display: grid; place-items: center; background: var(--ground); font-size: 14px; font-weight: 700; color: var(--ink-soft); }

/* The gallery card leads with its template's picture. */
.tpl-pic { display: block; width: calc(100% + 36px); max-width: none; height: auto; aspect-ratio: 2 / 1; object-fit: cover;
           margin: -18px -18px -6px; border-radius: var(--r) var(--r) 0 0; }   /* -6px: the card's own gap */
.tpl-pic + .tpl-art { height: 10px; margin-top: 0; border-radius: 0; }
.tpl-pic + .tpl-art > span { height: 100%; }
