/* The settings, auth and legal pages. The calendar has its own stylesheet.

   Every colour here comes from `tokens.css`, which this file no longer duplicates:
   GOAL-03 wrote its own small palette because there was no design system yet, and
   GOAL-08 built one. Two palettes would have meant a settings page that drifted
   away from the wall panel one hex code at a time, and a dark mode that covered
   only half the product.

   The two aliases below exist so the GOAL-03 markup did not have to be rewritten
   to say `--radius-md` everywhere. */

:root {
  --radius: var(--radius-md);
  --gap: var(--space-4);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.5 var(--font-sans);
}

.masthead {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap);
  padding: 0.75rem 1.25rem;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}

.brand { font-weight: 600; font-size: 1.1rem; color: var(--ink); text-decoration: none; }
.masthead nav { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }
.masthead nav a { color: var(--accent); text-decoration: none; }
.masthead nav a:hover { text-decoration: underline; }

main { padding: 1.25rem; max-width: 60rem; margin: 0 auto; }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem;
  margin-bottom: 1.25rem;
}
.card.narrow { max-width: 26rem; margin-left: auto; margin-right: auto; }

h1 { font-size: 1.4rem; margin-top: 0; }
h2 { font-size: 1.15rem; }
.hint { color: var(--ink-muted); font-size: 0.9rem; }

label { display: block; margin: 0.75rem 0 0.25rem; font-weight: 500; }
input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="time"], select {
  width: 100%;
  min-height: var(--touch-target);
  padding: 0.5rem 0.6rem;
  font: inherit;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
input:focus, select:focus, button:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

.code-input { font-family: var(--font-mono);
              font-size: 1.6rem; letter-spacing: 0.12em; text-align: center; }

button {
  min-height: var(--touch-target);
  margin-top: 0.75rem;
  padding: 0.5rem 1rem;
  font: inherit;
  color: var(--accent-ink);
  background: var(--accent);
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
}
button[disabled] { opacity: 0.4; cursor: default; }
.inline { display: inline; }
.inline button { margin-top: 0; }

/* Handing a chore out from a phone (2026-09-16). A select and a button on one line in a
   table cell, which the base rule would otherwise give the full width of the column. */
.assign-form { display: inline-flex; gap: 0.35rem; align-items: center; margin-top: 0.35rem; }
.assign-form select { width: auto; min-width: 7rem; }

/* A chore that is on no board: assigned to somebody who does not earn points. Said on
   the row, because every route answers 200 while it is invisible. */
.warn-tag {
  display: block;
  margin-top: 0.2rem;
  color: var(--error-ink);
  font-size: 0.85rem;
}
.linkish { background: none; color: var(--accent); border: none; padding: 0; min-height: 0; }

.flashes { list-style: none; margin: 1rem auto 0; padding: 0 1.25rem; max-width: 60rem; }
.flash { padding: 0.75rem 1rem; border-radius: var(--radius); margin-bottom: 0.5rem; }
.flash-error { background: var(--error-bg); color: var(--error-ink); }
.flash-notice { background: var(--notice-bg); color: var(--notice-ink); }
.field-error { color: var(--error-ink); font-size: 0.85rem; margin: 0.25rem 0 0; }

.grid { width: 100%; border-collapse: collapse; }
.grid th, .grid td { text-align: left; padding: 0.5rem; border-bottom: 1px solid var(--line);
                     vertical-align: top; }
.grid tr.inactive { opacity: 0.55; }
.nowrap { white-space: nowrap; }

.lanes { list-style: none; padding: 0; }
.lane { display: flex; align-items: center; gap: 0.75rem; padding: 0.5rem 0;
        border-bottom: 1px solid var(--line); }
/* The short name is always rendered alongside the colour, never instead of it
   (ADR-0008): colour is never the only encoding. */
.lane-chip { display: inline-block; min-width: 2.5rem; padding: 0.2rem 0.5rem; text-align: center;
             font-weight: 600; border: 1px solid var(--line); border-radius: var(--radius);
             background: var(--code-bg); }
.device-badge { color: var(--ink-muted); font-size: 0.9rem; }

code { background: var(--code-bg); padding: 0.1rem 0.3rem; border-radius: 4px;
       font-family: var(--font-mono); font-size: 0.9em; }

@media (max-width: 40rem) {
  .grid thead { display: none; }
  .grid tr { display: block; border-bottom: 2px solid var(--line); padding: 0.5rem 0; }
  .grid td { display: block; border: none; padding: 0.25rem 0; }
}

/* --- Google accounts and calendars (GOAL-04) ------------------------------- */

/* A short status word next to a thing, readable without relying on its colour. */
.pill { display: inline-block; padding: 0.1rem 0.5rem; margin-right: 0.25rem;
        font-size: 0.8rem; border: 1px solid var(--line); border-radius: 999px;
        background: var(--code-bg); color: var(--ink-muted); white-space: nowrap; }
.pill-ok  { background: var(--notice-bg); color: var(--notice-ink); border-color: transparent; }
.pill-bad { background: var(--error-bg);  color: var(--error-ink);  border-color: transparent; }

button.danger { background: var(--error-ink); color: var(--bg); }

/* A table that cannot shrink any further scrolls sideways inside its card, rather than
   spilling past the card's edge. The page itself must never scroll horizontally. */
.table-scroll { overflow-x: auto; }

/* Three buttons in one cell need to be narrower than a standalone form button, or the
   row cannot fit a laptop window. The full 44px touch height is kept -- only the
   horizontal padding and the label size give way. */
.grid td.actions { min-width: 10rem; }
.grid td.actions button { padding: 0.4rem 0.7rem; font-size: 0.9rem; margin-top: 0.25rem; }
.grid td.actions form { margin-right: 0.15rem; }

/* The two buttons that hand somebody over to Google's consent screen -- and only those
   two (Google branding guidelines, 2026-09-20). "Re-discover" and "Remove" act on this
   application's own rows, and wearing Google's mark there would read as endorsement.

   Nothing here is a design choice. The chrome is `--google-btn-*` in `tokens.css`,
   which carries Google's published light and dark values, and the mark is an <img> of
   a file rather than inline SVG so that no `fill`, `color` or `filter` on an ancestor
   can reach it -- an accidental monochrome G is a verification finding.

   `background` and `color` are overridden *together*. The base `button` rule sets both
   (accent fill, `--accent-ink` text), and overriding one alone is exactly how this
   codebase has twice shipped a correctly-sized, focusable, invisible button. */
.btn-google {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  padding: 0.5rem 0.75rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--google-btn-ink);
  background: var(--google-btn-bg);
  border: 1px solid var(--google-btn-line);
}

/* 18px flat, never an em: the guidelines forbid rescaling the mark against the label,
   so it must not ride the root font size the kiosk densities move. */
.btn-google .google-g { flex: none; width: 18px; height: 18px; }

/* The actions cell narrows every button in it. Height and the mark are left alone --
   only the label's breathing room gives way, and Google's 12px sides are kept. */
.grid td.actions .btn-google { padding: 0.4rem 0.75rem; }

.calendar-row { padding: 0.75rem 0; border-top: 1px solid var(--line); }
.calendar-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
/* Only the description dims when a calendar is gone upstream -- never the controls.
   The row is still editable (switching it off is a reasonable thing to want), and a
   greyed-out form reads as "you cannot touch this". */
.calendar-row.inactive .calendar-head,
.calendar-row.inactive .hint { opacity: 0.55; }
.calendar-row .hint { margin: 0.25rem 0 0.5rem; word-break: break-all; }

/* Google's own colour for a calendar. Purely decorative and aria-hidden: the calendar's
   name sits beside it, so unlike a person's lane colour it is never the only encoding. */
.calendar-swatch { display: inline-block; width: 1.5rem; height: 1.5rem; flex: none;
                   border: 1px solid var(--line); border-radius: 4px;
                   background: var(--code-bg); }

/* One row of controls per calendar, wrapping to a stack on a phone. */
.calendar-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.75rem; }
.calendar-form .field { flex: 1 1 12rem; }
.calendar-form .field-narrow { flex: 0 0 7rem; }
.calendar-form label { margin-top: 0; }
.calendar-form button { margin-top: 0; width: 100%; }
/* The "show this calendar" checkbox is a touch target on the wall panel too. */
.calendar-form input[type="checkbox"] { width: 1.25rem; height: 1.25rem;
                                       vertical-align: -0.15rem; margin-right: 0.35rem; }

/* Long-form legal text. Narrower measure than a settings page, because 60rem of
   unbroken paragraph is genuinely hard to read; headings get room to separate sections. */
.prose { max-width: 44rem; margin-left: auto; margin-right: auto; }
.prose h1 { margin-bottom: 0.25rem; }
.prose h2 { margin-top: 2rem; border-top: 1px solid var(--line); padding-top: 1.25rem; }
.prose h3 { margin-top: 1.5rem; font-size: 1rem; }
.prose h4 { margin-top: 1.25rem; font-size: 0.95rem; color: var(--ink-muted); }
.prose li { margin-bottom: 0.35rem; }
.prose li > p { margin: 0.25rem 0; }

/* A quiet link to the legal pages, out of the way of the actual task. */
.page-footer { max-width: 60rem; margin: 0 auto; padding: 1.5rem 1.25rem 2.5rem;
               color: var(--ink-muted); font-size: 0.85rem; }
.page-footer a { color: var(--ink-muted); }

/* The public home page: logo beside the name, stacking on a phone. */
.about-head { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem;
              margin-bottom: 1rem; }
.about-logo { border-radius: 18px; flex: none; }
.about-head h1 { margin: 0; }
.about-head .hint { margin: 0.25rem 0 0; }
.brand-mark { vertical-align: -0.35rem; border-radius: 6px; margin-right: 0.4rem; }
.brand { display: inline-flex; align-items: center; }

/* --- per-device display settings (GOAL-09) --------------------------------- */

/* A form with eleven fields reads as a wall of inputs in one column. Grouping them
   three to a row is the difference between "configure this screen" and "fill this in". */
.settings-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: var(--gap);
  margin-bottom: 1.25rem;
}
.settings-grid .field-narrow { max-width: 10rem; }
.settings-grid label { margin-top: 0; }
.settings-grid .hint { margin: 0.25rem 0 0; }
/* A link that has to sit in a row of buttons and look like one. */
.buttonish {
  display: inline-block;
  min-height: var(--touch-target);
  padding: 0.6rem 0.7rem;
  margin-right: 0.15rem;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  color: var(--accent);
  font-size: 0.9rem;
  text-decoration: none;
}
.buttonish:hover { background: var(--code-bg); }

/* --- checklists (GOAL-20) ------------------------------------------------------
   The admin side only. What a child sees is `calendar.css`, because it is a display
   view; this is the composer an adult uses on a laptop or a phone. */

.weekday-picker {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.5rem 0.75rem 0.75rem;
  margin: 0 0 1.25rem;
}
.weekday-picker legend { color: var(--ink-muted); font-size: 0.9rem; padding: 0 0.25rem; }
.weekday-picker ul { list-style: none; display: flex; flex-wrap: wrap; gap: 0.25rem 1rem;
  margin: 0; padding: 0; }
.weekday-picker li { display: flex; align-items: center; gap: 0.4rem; }
.weekday-picker input[type="checkbox"] { width: 1.25rem; height: 1.25rem; margin: 0; }
.weekday-picker label { margin: 0; font-weight: 400; }

.task-emoji { font-size: 1.25rem; line-height: 1; }

/* A household icon in the admin, drawn the same way the panel draws it -- masked, so
   the monochrome source takes the surrounding ink and works in both themes. See the
   note beside `.check-icon` in calendar.css. */
.task-icon {
  display: inline-block;
  width: 1.25rem;
  height: 1.25rem;
  vertical-align: -0.2em;
  background-color: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat;
  mask: var(--icon) center / contain no-repeat;
}
.task-cell-icon { width: 2rem; text-align: center; }

/* The picture picker (GOAL-22). Real `<input type="radio">`s, hidden from sight but not
   from the keyboard or a screen reader, with the `<label>` doing all the drawing. That
   is what buys the selected state, arrow-key navigation between options and a full
   touch target without a line of JavaScript -- and it is why `RadioField.pre_validate`
   can police the submission against the same list this rendered from. */
.icon-picker {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 0.35rem 0.75rem 0.75rem;
  margin: 0 0 1rem;
}
.icon-picker legend { padding: 0 0.3rem; color: var(--ink-muted); font-size: 0.9rem; }
.icon-group-name {
  margin: 0.75rem 0 0.35rem;
  color: var(--ink-muted);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.icon-grid {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin: 0;
  padding: 0;
}

/* Clipped rather than `display: none`, which would take the radio out of the tab order
   and off every screen reader -- the label alone is not focusable. */
.visually-hidden,
.icon-grid input[type="radio"],
.icon-option-other input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.icon-option {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--touch-target);
  height: var(--touch-target);
  margin: 0;
  font-size: 1.35rem;
  font-weight: 400;
  line-height: 1;
  background: var(--surface-sunk);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  cursor: pointer;
}
.icon-option:hover { background: var(--surface-inset); }

/* Inside the border rather than around it, so a selected option does not shove its
   neighbours along the row. */
.icon-grid input[type="radio"]:checked + .icon-option,
.icon-option-other:has(input[type="radio"]:checked) {
  background: var(--surface-inset);
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.icon-grid input[type="radio"]:focus-visible + .icon-option,
.icon-option-other:has(input[type="radio"]:focus-visible) {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.icon-art {
  width: 1.5rem;
  height: 1.5rem;
  background-color: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat;
  mask: var(--icon) center / contain no-repeat;
}
.icon-char { line-height: 1; }

/* "No picture" needs to look like an option rather than an empty square, or it reads as
   a rendering failure next to a grid of pictures. */
.icon-none-mark {
  width: 1.1rem;
  height: 1.1rem;
  border-radius: var(--radius-pill);
  border: 2px solid var(--ink-faint);
  position: relative;
  overflow: hidden;
}
.icon-none-mark::after {
  content: "";
  position: absolute;
  left: -15%;
  top: 45%;
  width: 130%;
  height: 2px;
  background: var(--ink-faint);
  transform: rotate(-45deg);
}

.icon-other { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.icon-option-other {
  width: auto;
  height: var(--touch-target);
  padding: 0 0.75rem;
  font-size: 0.95rem;
  gap: 0.4rem;
}
.icon-other input[type="text"] { width: 5rem; margin: 0; text-align: center; font-size: 1.2rem; }

/* The composed list. A row is a full touch target tall because the arrows and the
   remove button live in it, and this page gets used one-handed on a phone. */
.compose-list { list-style: none; margin: 0 0 0.75rem; padding: 0; }
.compose-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  margin-bottom: 0.35rem;
}
.compose-item.is-dragging { box-shadow: var(--shadow-2); opacity: 0.9; }
.compose-empty { color: var(--ink-muted); justify-content: center; }
.compose-label { flex: 1 1 auto; }
.compose-actions { display: flex; align-items: center; gap: 0.15rem; }
.compose-actions button { margin-top: 0; padding: 0.4rem 0.6rem; font-size: 0.9rem; }

/* `touch-action: none` is what makes a drag a drag on a touchscreen: without it the
   browser claims the gesture for scrolling and the pointermove events stop arriving
   after the first few pixels. Scoped to the handle so the rest of the page still
   scrolls normally under a finger. */
.drag-handle {
  cursor: grab;
  touch-action: none;
  color: var(--ink-faint);
  letter-spacing: -0.2em;
  padding: 0.5rem 0.35rem 0.5rem 0.15rem;
  user-select: none;
}
.drag-handle:active { cursor: grabbing; }

.library-list { list-style: none; display: flex; flex-wrap: wrap; gap: 0.5rem;
  margin: 0 0 0.75rem; padding: 0; }
.library-list form { margin: 0; }
.library-add {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0;
  padding: 0.5rem 0.75rem;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line);
}
.library-add:hover { border-color: var(--accent); }
.library-plus { color: var(--accent); font-weight: 700; }

/* "Open from 5:00 until 11:59" is one idea and lays out as one field. */
.window-field { grid-column: span 2; }
.window-inputs { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.window-inputs input { width: auto; margin-top: 0; }
.window-until { color: var(--ink-muted); }

/* --- the approval queue (GOAL-25) ----------------------------------------------
   Built phone-first: the wall panel never shows this page, and a parent approves
   standing in a kitchen holding a phone. Every control is a plain form, so the whole
   screen works with no JavaScript. */

/* The count an admin carries around. It is the whole reason a queue gets looked at,
   so it is a filled pill rather than a parenthesised number. */
.queue-badge {
  display: inline-block;
  min-width: 1.4em;
  padding: 0 0.4em;
  background: var(--accent);
  color: var(--surface);
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 700;
  line-height: 1.5;
  text-align: center;
}

.queue-person { margin: 1.25rem 0 0; }
.queue-person-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
}
.queue-swatch {
  flex: none;
  width: 0.8em;
  height: 0.8em;
  border-radius: 999px;
  background: var(--fill);
}
.queue-balance {
  margin-left: auto;
  color: var(--ink-muted);
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}

/* One claim, one row. It wraps on a phone rather than shrinking the buttons: a
   mis-tapped Approve is the one mistake on this page that needs a second decision
   to undo. */
.queue-claim {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 0.75rem;
  margin-bottom: 0.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 0.5rem;
}
.queue-what { flex: 1 1 12rem; min-width: 0; }
.queue-what .hint { display: block; }

.queue-decide { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0; flex: 1 1 auto; }
/* Wide enough for four digits and no wider: it is a default-filled override, not the
   primary control, and a full-width box reads as something that must be filled in. */
.queue-decide input[type="number"] { width: 5rem; margin-top: 0; }
.queue-decide input[type="text"] { flex: 1 1 8rem; min-width: 0; margin-top: 0; }
.queue-no-form { margin: 0; }

/* **Both colours, always.** The base `button` rule sets `color: var(--accent-ink)` on
   `background: var(--accent)`, so overriding the background alone left white text on a
   white button -- present, 84x44px, and completely invisible. Found by looking at the
   screen; nothing could have failed. */
.queue-yes { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.queue-no {
  background: var(--surface);
  color: var(--ink);
  border-color: var(--line-strong);
}

.queue-all { margin: 0.25rem 0 0; }

/* The participation tick on a person, and anywhere else a checkbox needs its label
   beside it rather than above it. */
.checkbox-field { display: flex; align-items: center; gap: 0.5rem; margin: 0.75rem 0 0; }
.checkbox-field input { width: auto; margin: 0; }
.checkbox-field label { margin: 0; }

/* --- quick edit and clone on the checklists list (2026-09-14) ------------------
   A row of text boxes in a table reads as a form to fill in rather than as a list to
   read. These are drawn as the value they hold -- no border, no box -- and become an
   input on hover, focus or touch. The name is still a real `<input>` the whole time,
   so tabbing into it works and there is no click-to-reveal state to get stuck in. */

/* `input.quick-input`, not `.quick-input`. The base rule is `input[type="text"], ...`,
   and an attribute selector counts the same as a class -- so `input[type=text]` is
   (0,1,1) and a bare class is (0,1,0), and the base rule wins every declaration these
   set. The symptom is a rule that is present in the stylesheet, matches the element,
   and changes nothing on screen, which reads as a stylesheet that failed to load.
   Matching the specificity and sitting later in the file is what settles it. */
input.quick-input {
  width: 100%;
  min-height: 0;
  margin: 0;
  padding: 0.25rem 0.35rem;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius);
}
input.quick-input:hover { border-color: var(--line); }
input.quick-input:focus { background: var(--surface); border-color: var(--accent); }
input.quick-name { min-width: 6.5rem; }
.quick-window { display: inline-flex; align-items: center; gap: 0.15rem; }
/* The native picker button is what makes these read as form widgets rather than as the
   value they hold, and it costs about 25px in each of two inputs -- which is most of
   what pushed Clone off the end of the row. The field is still typed into, still takes
   arrow keys, and on a phone still opens the system picker on focus; the full editor
   keeps its ordinary time inputs, icon and all. */
.quick-window input.quick-input::-webkit-calendar-picker-indicator { display: none; }

/* Four controls where every other settings table has two or three. A clipped button
   reads as a broken page rather than as a table that scrolls -- GOAL-17 learned that
   from a switcher whose sixth tab fell off a phone -- so this cell is a flex row that
   wraps, and the horizontal padding is trimmed (never the 44px touch height) so that at
   the width the card actually gets it does not have to. `.table-scroll` goes back to
   being the fallback it was meant to be rather than the only thing between an admin and
   a button they cannot see. */
.grid td.actions-wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem;
  white-space: normal;
}
.grid td.actions-wrap .buttonish,
.grid td.actions-wrap button { padding-left: 0.5rem; padding-right: 0.5rem; margin-right: 0; }
.grid td.actions-wrap form { margin-right: 0; }
/* `.inline` sets `display: inline`, and an author rule beats the UA's
   `[hidden] { display: none }` whatever the specificity -- the trap
   `tests/test_hidden_elements.py` exists for. Without this the form `quickedit.js`
   hides is still a flex item, and the row keeps a gap where a button used to be. */
.grid td.actions-wrap form[hidden] { display: none; }
/* A time input sizes itself to its content; letting it stretch would make the two ends
   of one window look like two separate columns. */
.quick-window input.quick-input { width: auto; }

/* The clone page's copy list. Checkboxes rather than an implicit copy: an afternoon
   routine is usually the morning minus two things, and unticking here is the saving. */
.clone-items {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.5rem 0.75rem 0.75rem;
  margin: 0 0 1.25rem;
}
.clone-items legend { color: var(--ink-muted); font-size: 0.9rem; padding: 0 0.25rem; }
.clone-list { list-style: none; margin: 0; padding: 0; }
.clone-item { display: flex; align-items: center; gap: 0.6rem; padding: 0.3rem 0; }
.clone-item input[type="checkbox"] { width: 1.25rem; height: 1.25rem; margin: 0; flex: none; }
.clone-item label { display: flex; align-items: center; gap: 0.5rem;
                    margin: 0; font-weight: 400; cursor: pointer; }

/* --- Infinite Campus on the person page and the People card (GOAL-24) --- */
.campus-fields {
  margin: 1.25rem 0 0.75rem;
  padding: 0.5rem 0.75rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
}
.campus-fields legend { padding: 0 0.25rem; font-weight: 600; }
.campus-show-label { margin: 0.75rem 0 0; }
.campus-status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  margin: 1rem 0;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius-md);
  background: var(--surface-inset);
}
.campus-status-line { margin: 0; flex: 1 1 14rem; }
.campus-status .hint { flex-basis: 100%; margin: 0; }
.campus-links { margin: 0.5rem 0 0.75rem; padding-left: 1.25rem; }
