/*
 * Weave.
 *
 * Design rules that are not negotiable, because they are the product:
 *   - No red. There is no failure state in this palette, because there is no
 *     failure state in the product.
 *   - Type large enough to read at arm's length, outdoors, in sun.
 *   - Tap targets >= 48px, reachable one-handed, primary actions low on screen.
 *   - Warmth over neutrality. This should feel like a kitchen, not a console.
 */

:root {
  color-scheme: light dark;

  --paper:      #faf6f0;
  --card:       #fffdfa;
  --ink:        #2b2621;
  --ink-soft:   #6b6158;
  --ink-faint:  #756b62;   /* 4.8:1 on paper — small meta text has to survive sunlight */
  --line:       #e6ddd1;

  --accent:     #a94c1a;   /* terracotta: warm, high contrast, never alarming */
  --accent-ink: #ffffff;
  --accent-wash:#fbeee4;

  --settled:    #3f6d4d;   /* the green of something finished, used sparingly */
  --settled-wash:#e8f1e9;

  --radius: 14px;
  --shadow: 0 1px 2px rgba(43, 38, 33, .06), 0 4px 14px rgba(43, 38, 33, .05);
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper:      #1c1916;
    --card:       #262220;
    --ink:        #f2ece4;
    --ink-soft:   #b8ada1;
    --ink-faint:  #8a8078;
    --line:       #3a342f;
    --accent:     #e8884f;
    --accent-ink: #1c1916;
    --accent-wash:#3a2a20;
    --settled:    #8fc0a0;
    --settled-wash:#26332a;
    --shadow: none;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 17px/1.5 ui-rounded, "SF Pro Rounded", -apple-system, BlinkMacSystemFont,
        "Segoe UI", system-ui, sans-serif;
  -webkit-text-size-adjust: 100%;
  padding-bottom: 4rem;
}

.wrap { max-width: 34rem; margin: 0 auto; padding: 1rem 1.1rem 0; }

/* --- Header ---------------------------------------------------------------- */
header.bar {
  display: flex; align-items: baseline; gap: .6rem;
  padding: 1.1rem 0 .4rem;
}
header.bar h1 { font-size: 1.35rem; margin: 0; letter-spacing: -.01em; }
header.bar .event { color: var(--ink-soft); font-size: .95rem; }

a.back {
  display: inline-block; color: var(--ink-soft); text-decoration: none;
  font-size: .95rem; padding: .5rem 0; min-height: 44px; line-height: 34px;
}
a.back:hover { color: var(--accent); }

/* --- Cards ----------------------------------------------------------------- */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.1rem;
  margin: 0 0 1rem;
}

/* The welcome-back card. Deliberately the warmest thing on the page. */
.resume {
  background: var(--accent-wash);
  border-color: color-mix(in srgb, var(--accent) 25%, transparent);
}
.resume .lead { font-size: 1.15rem; font-weight: 600; margin: 0 0 .5rem; }
.resume .what { font-size: 1.25rem; line-height: 1.35; margin: 0 0 .6rem; }
.resume .snippet {
  font-style: italic; color: var(--ink-soft);
  border-left: 3px solid color-mix(in srgb, var(--accent) 40%, transparent);
  padding-left: .75rem; margin: 0 0 1rem;
  white-space: pre-wrap;
}

/* --- Section headings ------------------------------------------------------ */
h2.section {
  font-size: .82rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--ink-faint); font-weight: 700;
  margin: 1.7rem 0 .6rem;
}
.blurb { color: var(--ink-soft); font-size: .95rem; margin: -.3rem 0 .7rem; }

/* --- Task rows ------------------------------------------------------------- */
ul.tasks { list-style: none; margin: 0; padding: 0; }
ul.tasks li { border-bottom: 1px solid var(--line); }
ul.tasks li:last-child { border-bottom: 0; }

/* The layout is shared: a task row in a list is a link, and the same row in the
   paste preview is not one yet, but they should look identical. */
.task {
  display: flex; align-items: flex-start; gap: .75rem;
  padding: .95rem .2rem; min-height: 56px;
  color: var(--ink); text-decoration: none;
}
a.task:hover { background: color-mix(in srgb, var(--accent) 5%, transparent); }
.task .title { font-size: 1.05rem; line-height: 1.35; }
.task .meta {
  display: flex; flex-wrap: wrap; gap: .45rem; align-items: center;
  margin-top: .3rem; font-size: .87rem; color: var(--ink-faint);
}
.task .note-flag { color: var(--accent); }

/* Status dot. Four calm states, and still nothing anywhere for "this one is late". */
.dot {
  width: 11px; height: 11px; border-radius: 50%; flex: 0 0 11px; margin-top: .45rem;
  border: 2px solid var(--ink-faint);
}
.dot.doing { border-color: var(--accent); background: var(--accent); }
.dot.done  { border-color: var(--settled); background: var(--settled); }
/* Set aside: filled with the hairline colour, so it reads as closed rather than as
   flagged. A decision the group made is not a warning about anybody. */
.dot.aside { border-color: var(--line); background: var(--line); }

.pill {
  display: inline-block; padding: .18rem .5rem; border-radius: 999px;
  font-size: .78rem; background: var(--accent-wash); color: var(--accent);
  font-weight: 600;
}
.pill.settled { background: var(--settled-wash); color: var(--settled); }
.pill.quiet { background: transparent; color: var(--ink-faint); font-weight: 500; padding-left: 0; }
/* An invitation, so it wears the accent — the same warmth as "Could use 2 more" on the board. */
.pill.hand { background: transparent; color: var(--accent); box-shadow: inset 0 0 0 1.5px var(--accent); }

/* --- Buttons --------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 50px; padding: .8rem 1.2rem;
  border-radius: 999px; border: 1.5px solid var(--line);
  background: var(--card); color: var(--ink);
  font: inherit; font-weight: 600; font-size: 1rem;
  text-decoration: none; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn.primary:hover { filter: brightness(1.06); color: var(--accent-ink); }
.btn.wide { width: 100%; }
.btn.quiet { border-color: transparent; color: var(--ink-soft); font-weight: 500; }
.btn.quiet:hover { color: var(--accent); }

.actions { display: flex; flex-wrap: wrap; gap: .6rem; }
.actions .btn { flex: 1 1 auto; }

/* --- The left-off note: the most important field in the product ------------ */
.leftoff label { display: block; font-weight: 600; margin-bottom: .2rem; }
.leftoff .hint { color: var(--ink-soft); font-size: .9rem; margin: 0 0 .6rem; }
.leftoff textarea {
  width: 100%; min-height: 8.5rem; resize: vertical;
  padding: .85rem; border-radius: 12px;
  border: 1.5px solid var(--line); background: var(--paper); color: var(--ink);
  font: inherit; line-height: 1.5;
}
.leftoff textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent; }
.save-state { font-size: .85rem; color: var(--ink-faint); min-height: 1.3em; margin-top: .35rem; }

/* Somebody else's note, or one left on a task nobody is holding. Set as quoted
   speech rather than as a disabled textarea: a greyed-out box says "you may not",
   and this is not a thing being withheld — it is a sentence someone wrote to
   themselves, being passed on intact. */
.leftoff .leftoff-read {
  margin: 0; padding: .1rem 0 .1rem .9rem;
  border-left: 2px solid var(--line);
  color: var(--ink-soft); line-height: 1.5;
}

/* --- Tally: an accumulation, never a fraction ------------------------------ */
.tally { color: var(--ink-soft); font-size: .95rem; text-align: center; margin: 1.6rem 0 .5rem; }

/* --- Join ------------------------------------------------------------------ */
.join-input {
  width: 100%; padding: .95rem 1rem; font: inherit; font-size: 1.2rem;
  border-radius: 12px; border: 1.5px solid var(--line);
  background: var(--card); color: var(--ink); text-align: center;
  letter-spacing: .04em;
}
.join-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

ul.people { list-style: none; margin: 0; padding: 0; }
ul.people li { margin-bottom: .55rem; }
ul.people button {
  width: 100%; text-align: left; min-height: 58px;
  padding: .9rem 1.1rem; font: inherit; font-size: 1.08rem;
  background: var(--card); color: var(--ink);
  border: 1.5px solid var(--line); border-radius: 12px; cursor: pointer;
}
ul.people a {
  display: block; text-align: left; min-height: 58px;
  padding: 1.1rem; font-size: 1.08rem;
  background: var(--card); color: var(--ink); text-decoration: none;
  border: 1.5px solid var(--line); border-radius: 12px;
}
ul.people button:hover, ul.people a:hover { border-color: var(--accent); }
ul.people .layer { color: var(--ink-faint); font-size: .85rem; }

.empty { color: var(--ink-soft); padding: .8rem 0; }
.cheer {
  background: var(--settled-wash); color: var(--settled);
  border-radius: var(--radius); padding: .9rem 1.1rem;
  font-weight: 600; margin-bottom: 1rem;
}

/* =========================================================================
   The event-day board.

   Different design problem from the planning screens: read at arm's length,
   outdoors, in sun, one-handed, while someone shouts your name. So the type
   steps up, the targets get bigger, and every action is a single tap with no
   confirmation step in the way.
   ========================================================================= */

body.board { font-size: 18px; }

body.board h2.section { font-size: .92rem; margin-top: 2rem; }

[x-cloak] { display: none !important; }

.preview {
  background: var(--accent-wash); color: var(--accent);
  border-radius: 10px; padding: .5rem .8rem; font-size: .9rem; font-weight: 600;
  margin: 0 0 1rem;
}

/* Anything a tap could not deliver yet. The app's problem, not the person's. */
.queued {
  background: var(--accent-wash); color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: var(--radius); padding: .8rem 1rem;
  font-size: .95rem; font-weight: 600; margin-bottom: 1rem;
}

/* --- Shifts --------------------------------------------------------------- */
.shift .shift-head {
  display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: .4rem; margin-bottom: .6rem;
}
.shift .shift-title { font-size: 1.35rem; font-weight: 700; line-height: 1.25; }
.shift .shift-time { color: var(--ink-soft); font-size: 1rem; font-variant-numeric: tabular-nums; }

/* A running shift is the one thing on screen that should catch the eye first. */
.shift.live {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  border-width: 2px;
  background: color-mix(in srgb, var(--accent-wash) 55%, var(--card));
}

.shift .who { margin: 0 0 .6rem; display: flex; flex-wrap: wrap; gap: .35rem; }
.shift .who .nobody { color: var(--ink-faint); font-style: italic; }
.shift .want { margin: 0 0 .9rem; }

.shift .im-in {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: .5rem;
}

/* --- Jobs ----------------------------------------------------------------- */
.job {
  display: flex; align-items: center; justify-content: space-between;
  gap: .9rem; padding: .85rem 0;
  border-bottom: 1px solid var(--line);
}
.job:last-child { border-bottom: 0; }
.job .job-title { font-size: 1.1rem; line-height: 1.3; }
.job .btn { flex: 0 0 auto; min-height: 52px; }
.job.settled-job .job-title { color: var(--ink-soft); }

/* --- The optimistic flip -------------------------------------------------- */
/* A tap has to feel answered instantly, before the network has any say. */
.tap { transition: transform .08s ease, background-color .12s ease, border-color .12s ease; }
.tap:active { transform: scale(.97); }
.tap.tapped {
  background: var(--settled-wash);
  border-color: var(--settled);
  color: var(--settled);
}

/* The flip's confirmation is presentational, so the label stays in messages.properties
   and cannot drift out of the tone contract's sight. */
.tap.tapped::after { content: " ✓"; }

/* =========================================================================
   The hug.

   What a hug is, mechanically: a brief gentle squeeze, warmth spreading
   outward, and then it lets go on its own. It asks nothing of you and it
   does not wait to be dismissed.

   What it deliberately is not: confetti, a trophy, a sound, a score, or
   anything that gets bigger the more you finish. A reward implies somebody
   keeping count, and the moment a volunteer senses a tally they are back
   to being measured. The tenth hug is exactly the first hug.
   ========================================================================= */

@keyframes hug {
  0%   { transform: scale(1);
         box-shadow: inset 0 0 0 999px transparent,             0 0 0 0    transparent; }
  32%  { transform: scale(.978);
         box-shadow: inset 0 0 0 999px var(--settled-wash),     0 0 0 13px var(--settled-wash); }
  100% { transform: scale(1);
         box-shadow: inset 0 0 0 999px transparent,             0 0 0 13px transparent; }
}

@keyframes hug-arrive {
  0%   { opacity: 0; transform: translateY(-5px); background: var(--settled-wash); }
  100% { opacity: 1; transform: translateY(0);    background: transparent; }
}

/* The squeeze lands on whatever the person actually touched. */
.task-head { margin-bottom: 1.1rem; border-radius: var(--radius); }

.hugged {
  animation: hug 820ms cubic-bezier(.34, .12, .2, 1) both;
  border-radius: var(--radius);
}

/* A row settling into "Wrapped up" — the warmth arriving where the task went. */
.just-wrapped { animation: hug-arrive 620ms ease-out both; }

/* The banner rises gently, sits for a moment, then recedes. No close button:
   a hug that needed dismissing would not be a hug. */
.cheer {
  animation: cheer-in 420ms ease-out both, cheer-out 700ms ease-in 4.2s both;
  transform-origin: top center;
  overflow: hidden;
}

@keyframes cheer-in {
  from { opacity: 0; transform: translateY(-7px) scale(.985); }
  to   { opacity: 1; transform: translateY(0)    scale(1); }
}

@keyframes cheer-out {
  from { opacity: 1; max-height: 8rem; margin-bottom: 1rem; padding-top: .9rem; padding-bottom: .9rem; }
  to   { opacity: 0; max-height: 0;    margin-bottom: 0;    padding-top: 0;     padding-bottom: 0; }
}

/*
   Motion sensitivity is not an edge case in this audience. Someone reading this
   on a phone in a car park with a four-year-old on one leg has every reason to
   have motion turned down. They still get the hug — it just arrives as warmth
   settling rather than anything that moves.
*/
@media (prefers-reduced-motion: reduce) {
  @keyframes hug {
    0%   { box-shadow: inset 0 0 0 999px var(--settled-wash); }
    100% { box-shadow: inset 0 0 0 999px transparent; }
  }
  .hugged       { animation: hug 900ms ease-out both; transform: none; }
  .just-wrapped { animation: none; }
  .cheer        { animation: cheer-out 500ms ease-in 4.6s both; }
}

/* --- Putting something in --------------------------------------------------
   One box on top, the optional bits underneath. Stacked rather than inline so the
   input keeps its full width on a phone held in one hand. */
.add-card { padding-top: .9rem; padding-bottom: .9rem; }
.add-input, .field {
  width: 100%; padding: .85rem 1rem; font: inherit; font-size: 1.05rem;
  border-radius: 12px; border: 1.5px solid var(--line);
  background: var(--paper); color: var(--ink);
}
.add-input:focus, .field:focus {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent;
}
select.field { background: var(--card); }

.add-row { display: flex; gap: .6rem; margin-top: .6rem; }
.add-row .btn { flex: 0 0 auto; }
/* Where there is no area picker — home, and the event-day board — the button is on
   its own and takes the full width, so it stays a thumb-sized target rather than a
   small thing stranded in the corner. */
.add-row .btn:only-child { flex: 1 1 auto; }
.add-area {
  flex: 1 1 auto; min-width: 0;
  padding: .7rem .9rem; font: inherit;
  border-radius: 999px; border: 1.5px solid var(--line);
  background: var(--card); color: var(--ink);
}

/* --- The day itself ---------------------------------------------------------
   Under the name on home and under the heading on the plan, in the same register as
   a blurb: present, and quiet about it. A link, because tapping the day to change
   the day is what anyone would try first. There is no countdown and there will not
   be one — a distance escalates every morning toward a moment where what is left
   over reads as failure. */
.day-line { margin: -.3rem 0 1rem; font-size: .95rem; }
.day-line a {
  color: var(--ink-soft); text-decoration: none;
  border-bottom: 1px dotted var(--line); padding-bottom: 1px;
}
.day-line a:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* Which event a printed sheet belongs to. Never on a screen: you got here by link
   and the page around you already says. Face-down on a trestle table it is the only
   thing that tells you what you are holding. */
.paper-stamp { display: none; }

/* --- One person's sheet -----------------------------------------------------
   What somebody is down for, read rather than worked. The shift lines carry no
   controls at all: joining and stepping off belong on the board, where the person
   doing it is standing in the car park, and a second set here would be two places
   for the same decision to be half-made. */
.who-heading { margin: 0 0 .5rem; font-weight: 700; font-size: .95rem; color: var(--ink-soft); }
.who-shift {
  display: flex; flex-wrap: wrap; justify-content: space-between;
  gap: .15rem .8rem; padding: .55rem 0; border-bottom: 1px solid var(--line);
}
.who-shift:last-child { border-bottom: 0; padding-bottom: 0; }
.who-shift-title { font-size: 1.05rem; line-height: 1.35; }
.who-shift-when { color: var(--ink-soft); font-size: .95rem; font-variant-numeric: tabular-nums; }
.who-shift-when span + span { margin-left: .45rem; }

/* A name worth tapping, marked the same quiet way the day is. */
a.pill.who-link { text-decoration: none; border-bottom: 1px dotted var(--line); }
a.pill.who-link:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* --- Changing a task, and the quiet shelf of things set aside ---------------
   Both are folded away by default. Neither is something anyone should have to
   scroll past on the way to the work. */
details.edit-block, details.aside-block, details.areas-block { margin-top: 1.5rem; }

/* Reshaping the plan: a name to correct, two places to move it, one way out. Laid
   out as rows that wrap, so the controls stay reachable with a thumb rather than
   shrinking to fit a phone. */
.area-row { display: flex; flex-direction: column; gap: .5rem; }
.area-line { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.area-line .field { flex: 1 1 12rem; }
details > summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: baseline; gap: .6rem;
  padding: .7rem .2rem; min-height: 44px;
  font-weight: 600; color: var(--ink-soft);
}
details > summary::-webkit-details-marker { display: none; }
details > summary::after { content: "›"; margin-left: auto; transition: transform .15s ease; }
details[open] > summary::after { transform: rotate(90deg); }
details > summary:hover { color: var(--accent); }

.edit-block label { display: block; font-weight: 600; margin-bottom: .25rem; }
.edit-block textarea {
  width: 100%; resize: vertical; padding: .85rem; border-radius: 12px;
  border: 1.5px solid var(--line); background: var(--paper); color: var(--ink);
  font: inherit; line-height: 1.5;
}
.edit-block textarea:focus {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent;
}
.hint { color: var(--ink-soft); font-size: .9rem; margin: 0 0 .6rem; }

/* The way back, offered beside the thing that happened rather than as a question
   asked in front of it. */
.undo-line { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }
.undo-line form { margin: 0; }
.undo-line .btn { min-height: 40px; padding: .35rem 1rem; }

/* Who a task is waiting on: one box and a button on one line, wrapping on a narrow phone. */
.waiting label { display: block; font-weight: 600; margin-bottom: .2rem; }
.waiting .waiting-line { display: flex; flex-wrap: wrap; gap: .5rem; }
.waiting .waiting-line input {
  flex: 1 1 12rem; min-width: 0; min-height: 44px; padding: .5rem .75rem;
  border-radius: 10px; border: 1.5px solid var(--line); background: var(--paper);
  color: var(--ink); font: inherit;
}
.waiting .waiting-line input:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent; }
.waiting .btn.quiet { margin-top: .4rem; padding-left: 0; }
.resume .waiting-note { margin: -.3rem 0 .7rem; color: var(--ink-soft); }

/* Who to ask about an area: under its heading, and on its tasks. */
.ask-line { margin: -.3rem 0 .6rem; color: var(--ink-soft); font-size: .92rem; }
.ask-line a { color: var(--accent); }
.area-ask { display: flex; flex-wrap: wrap; align-items: flex-end; gap: .5rem .7rem; margin: .5rem 0; }
.area-ask label { flex: 1 1 10rem; min-width: 0; font-size: .85rem; color: var(--ink-soft); }
.area-ask select { width: 100%; margin-top: .2rem; }
.who-asked { margin: 0; }

/* A web address inside a note. Long ones (a Google Doc is 120 characters) break
   anywhere rather than pushing the page sideways on a phone. */
.note-link { color: var(--accent); overflow-wrap: anywhere; word-break: break-word; }

/* --- Pasting a whole list ---------------------------------------------------
   The box is big on purpose: what goes in it is twenty-five lines out of a
   spreadsheet, and a three-line box makes that feel like it will not fit. */
.paste-box {
  width: 100%; min-height: 14rem; resize: vertical;
  padding: .85rem; border-radius: 12px;
  border: 1.5px solid var(--line); background: var(--paper); color: var(--ink);
  font: inherit; font-size: .98rem; line-height: 1.5;
  white-space: pre; overflow-wrap: normal; overflow-x: auto;
}
.paste-box:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent; }

.paste-area {
  display: flex; align-items: center; gap: .5rem;
  margin: 1.4rem 0 .5rem; font-size: 1rem; font-weight: 700;
}
/* What came out of a spare spreadsheet column — present, and quiet about it. */
.paste-note {
  display: block; margin-top: .3rem;
  color: var(--ink-faint); font-size: .88rem; white-space: pre-wrap;
}
.paste-link { display: inline-block; margin-top: .8rem; color: var(--accent); font-size: .95rem; }

/* --- Planning the day -------------------------------------------------------
   The kitchen-table screen, weeks before the board gets carried outside. */
.form-fields label { display: block; font-weight: 600; margin-bottom: .25rem; }
.time-pair { display: flex; gap: .7rem; margin-top: .9rem; }
.time-pair > div { flex: 1 1 0; min-width: 0; }

/* Its own head rather than the board's: the board's 1.35rem title is sized to be read
   at arm's length in sunlight, which is the wrong weight for a list you are editing. */
.shift-row .shift-head {
  display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: .3rem .8rem;
}
.shift-row .shift-title { font-size: 1.15rem; font-weight: 700; line-height: 1.3; }
.shift-row .shift-time { color: var(--ink-soft); font-size: .95rem; font-variant-numeric: tabular-nums; }
.shift-row .who { margin: 0 0 .4rem; color: var(--ink-soft); font-size: .95rem; }
.shift-row .who .nobody { color: var(--ink-faint); font-style: italic; }
.shift-row .want { margin: 0 0 .7rem; }
.shift-row details.edit-block { margin-top: .4rem; }

/* A checkbox and its words, as one target big enough for a thumb. */
.check {
  display: flex; align-items: center; gap: .6rem;
  margin-top: 1rem; min-height: 44px;
  font-weight: 600; cursor: pointer;
}
.check input { width: 20px; height: 20px; accent-color: var(--accent); flex: 0 0 auto; }

/* --- Coming from a document -------------------------------------------------
   Folded away above the box. The prompt is long on purpose — the rules in it are
   what keep an assistant from inventing work — so it sits in a short scrolling
   window rather than pushing the actual paste box off the screen. */
.prompt-block .prompt-text {
  min-height: 9rem; margin-top: .7rem;
  color: var(--ink-soft); font-size: .85rem;
  white-space: pre-wrap; overflow-wrap: break-word;
}
/* The round trip, numbered. Sized like a hint rather than like instructions: it is
   a map of three steps, not a form to work through. */
ol.steps {
  margin: .2rem 0 .9rem; padding-left: 1.3rem;
  color: var(--ink-soft); font-size: .9rem; line-height: 1.5;
}
ol.steps li { margin-bottom: .2rem; }
ol.steps li::marker { color: var(--accent); font-weight: 700; }

.prompt-kinds { display: flex; flex-wrap: wrap; gap: .5rem; }
.prompt-kinds a {
  padding: .45rem .9rem; border-radius: 999px;
  border: 1.5px solid var(--line); background: var(--card);
  color: var(--ink-soft); font-size: .9rem; font-weight: 600; text-decoration: none;
}
.prompt-kinds a.here { border-color: var(--accent); color: var(--accent); }
/* Said beside the button that sends it, in the same quiet register as any other
   hint. Nothing is being warned about; this is where the material goes. */
.prompt-block .prompt-privacy { margin: 0; flex: 1 1 14rem; }

/* The file itself. A native picker, because it is the one a phone already knows. */
.sheet-block form { margin-top: .4rem; }
.sheet-block .sheet-file { display: block; width: 100%; max-width: 100%; font: inherit; font-size: .95rem; }
.sheet-block .check { margin-top: .6rem; }
.sheet-block .sheet-unreadable { color: var(--ink); }


/* --- On paper ---------------------------------------------------------------
   Event day happens in a field, and the signal there is whatever the field feels
   like giving. Print is the offline mode that actually ships: the plan on a
   clipboard, the board on a wall, and a box beside every name because somebody is
   standing at the gate ticking people off as they arrive.

   Two rules. Everything that exists to be tapped comes out, since a button on paper
   is a lie — and the ink goes black, because a printer handed a warm palette returns
   a grey page and this has to be readable at a trestle table. */
@media print {
  :root {
    --paper: #fff;  --card: #fff;
    --ink: #000;    --ink-soft: #333;  --ink-faint: #444;
    --line: #999;
    --accent: #000; --accent-ink: #fff; --accent-wash: #fff;
    --settled: #000; --settled-wash: #fff;
    --shadow: none;
  }

  @page { margin: 14mm; }

  body, body.board { font-size: 10.5pt; padding: 0; background: #fff; color: #000; }
  .wrap { max-width: none; margin: 0; padding: 0; }

  /* Nothing to tap, nothing to type into, and nothing still folded away: a details
     block that printed closed would print as a heading with its contents missing. */
  button, .btn, .actions, form, a.back, .add-card, .queued, .preview,
  .paste-link, .im-in, details { display: none !important; }

  a { color: inherit; text-decoration: none; }
  .day-line a { border-bottom: 0; }

  .card {
    box-shadow: none; border: 1px solid var(--line);
    margin-bottom: .5rem; break-inside: avoid; page-break-inside: avoid;
  }
  h2.section { margin-top: 1rem; break-after: avoid; page-break-after: avoid; }
  ul.tasks li { break-inside: avoid; page-break-inside: avoid; }

  /* Which event this sheet is about. The board and the plan are both titled for what
     they are rather than whose they are, which is fine on a phone that got there by
     link and useless on a page somebody finds face-down on a table. */
  .paper-stamp { display: block; font-weight: 600; margin: .1rem 0 .6rem; }

  /* The clipboard column. Drawn rather than typed, because a ballot-box character is
     at the mercy of whatever font the printer falls back to. */
  .shift .who .pill::before, .shift-row .who .pill::before {
    content: ""; display: inline-block;
    width: .85em; height: .85em; margin-right: .4em; vertical-align: -.05em;
    border: 1px solid #000;
  }
  .shift .who .pill, .shift-row .who .pill { color: #000; padding-left: 0; }

  /* Same box on the jobs, for the same reason: on the screen they are a tap, and on
     paper a tap is a pen. Not on the ones already wrapped up — a box beside something
     finished is asking for it to be done again. */
  .job:not(.settled-job) .job-title::before {
    content: ""; display: inline-block;
    width: .85em; height: .85em; margin-right: .5em; vertical-align: -.05em;
    border: 1px solid #000;
  }
}
