/* Margin Application Manager — shell styles (spec §9 information architecture,
   §20 responsive/interaction, §21 accessibility).

   Palette is the same paper/ink/pen system as the essay product (public/index.html)
   so the two products read as one platform. What is different here is the
   restraint: no progress bars, no percentages, no red. Spec §3.6 rules out
   streaks, shame language and failure banners, and §10.4 rules out "overdue" as a
   state — so there is deliberately no .is-overdue, .danger or .warning class in
   this file for a future view to reach for. Time conditions are shown as neutral
   text, and every status carries a word, never only a colour (§20.3). */

:root {
  --paper: #FAF7F0;
  --frame: #ECE4DA;
  --paper-line: #E4DECF;
  --ink: #23303F;
  --ink-soft: #5B6672;
  --pencil: #6E6559;
  /* The boundary of a form control is the only thing identifying it, so WCAG
     2.2 SC 1.4.11 wants 3:1 against BOTH the fill and the surface around it.
     --paper-line is decorative and stays soft; anything you can type in,
     choose from or press uses this instead. */
  --field-line: #847A66;
  --pen: #4E7A6C;
  --pen-soft: #E4EDE9;
  --pen-deep: #3C6154;
  --gold: #B9922F;
  --gold-soft: #F3E8CB;
  --focus: #1F5F8B;

  --nav-width: 232px;
  --bottom-nav-height: 60px;
  --radius: 12px;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

body {
  background: var(--frame);
  color: var(--ink);
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing: antialiased;
  font-size: 16px;
  line-height: 1.5;
}

/* §21: keyboard users get a real, visible focus ring everywhere, and it is never
   removed by a later rule. Colour alone is not relied on — the ring has width. */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: 4px;
}

/* §21 "reduced-motion support". */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--ink);
  color: #fff;
  padding: 12px 18px;
  z-index: 100;
  border-radius: 0 0 8px 0;
}
.skip-link:focus { left: 0; }

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */
.app {
  display: grid;
  /* minmax(0, 1fr), NOT 1fr. §21 requires zoom and reflow without loss of
     functionality, and a bare 1fr cannot deliver it: grid and flex items default
     to min-width:auto, so their MIN-CONTENT width becomes a floor. One
     unbreakable string — a 200-character title, a pasted URL inside a
     500-character note — pushes the column past the viewport and the whole
     document scrolls sideways. Measured at 1040px: the column blew out to 980px
     and the document scrolled to 2096px inside a 1025px viewport. minmax(0, ...)
     removes the floor so the column can shrink; the wrapping rules below then
     make the text fold instead of overflowing. */
  grid-template-columns: var(--nav-width) minmax(0, 1fr);
  min-height: 100vh;
  background: var(--paper);
}

.sidebar {
  border-right: 1px solid var(--paper-line);
  padding: 20px 14px 40px;
  display: flex;
  flex-direction: column;
  gap: 22px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.main {
  padding: 28px 32px 96px;
  max-width: 980px;
  width: 100%;
  min-width: 0;
}

/* The other half of the reflow fix. Removing the floor lets the column shrink;
   this is what stops the text sticking out of it afterwards. `anywhere` rather
   than `break-word`, because only `anywhere` also reduces the MIN-CONTENT width
   — which is the measurement the grid was reading in the first place.

   Applied to what people type — titles, names, notes, values — and not to the
   shell, so ordinary prose still breaks on spaces. */
.task-title, .task-meta, .task-note, .people-name, .people-meta,
.field-value, .panel p, .empty p, .page-head h1, .page-head p,
.notice, .disclaimer, .chip, .build-note, .status-line {
  overflow-wrap: anywhere;
}

/* Flex items carry the same min-content floor as grid items, and every one of
   these holds user text. */
.task-list li, .people-list li, .choice, .filters, .field-check { min-width: 0; }
.task-list li > *, .people-list li > * { min-width: 0; }

/* §20.1: 320px phone is a tested breakpoint, and §26.5 requires no horizontal
   scrolling. Below 900px the sidebar becomes a bottom bar of five (§9.1). */
@media (max-width: 899px) {
  .app { grid-template-columns: 1fr; }
  .sidebar { display: none; }
  .main { padding: 20px 16px calc(var(--bottom-nav-height) + 28px); }
}

/* --------------------------------------------------------------------------
   Brand + workspace switcher (§9.2)
   -------------------------------------------------------------------------- */
.brand {
  font-family: 'Caveat', cursive;
  font-weight: 700;
  font-size: 30px;
  line-height: 1;
  color: var(--ink);
  text-decoration: none;
  display: block;
}
.brand .dot { color: var(--pen); }
.brand-sub {
  font-family: 'Inter', sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pencil);
  margin-top: 6px;
}

.switcher { position: relative; }
.switcher-label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--pencil);
  margin-bottom: 6px;
}
.switcher select {
  width: 100%;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--field-line);
  border-radius: 8px;
  padding: 10px 10px;
  min-height: 44px;
}

/* --------------------------------------------------------------------------
   Navigation
   -------------------------------------------------------------------------- */
.nav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }

.nav a {
  display: flex;
  align-items: center;
  gap: 10px;
  /* §20.3 "minimum comfortable touch targets" — 44px, phone and desktop alike. */
  min-height: 44px;
  padding: 8px 12px;
  border-radius: 8px;
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 15px;
  font-weight: 500;
}
.nav a:hover { background: var(--frame); color: var(--ink); }

/* The current destination is marked by weight, background AND aria-current —
   never by colour alone (§20.3). */
.nav a[aria-current="page"] {
  background: var(--pen-soft);
  color: var(--pen-deep);
  font-weight: 600;
}


.nav-section-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--pencil);
  padding: 14px 12px 4px;
}

/* Mobile bottom bar — exactly five destinations (§9.1). */
.bottom-nav { display: none; }

@media (max-width: 899px) {
  .bottom-nav {
    display: block;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    background: var(--paper);
    border-top: 1px solid var(--paper-line);
    padding-bottom: env(safe-area-inset-bottom);
    z-index: 20;
  }
  .bottom-nav ul {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(5, 1fr);
  }
  .bottom-nav a {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-height: var(--bottom-nav-height);
    padding: 6px 2px;
    color: var(--ink-soft);
    text-decoration: none;
    font-size: 11px;
    font-weight: 500;
    text-align: center;
  }
  .bottom-nav a[aria-current="page"] { color: var(--pen-deep); font-weight: 700; }
  .bottom-nav }

/* --------------------------------------------------------------------------
   Page header + content blocks
   -------------------------------------------------------------------------- */
.page-head { margin-bottom: 24px; }
.page-head h1 {
  font-family: 'Source Serif 4', Georgia, serif;
  font-size: 30px;
  font-weight: 600;
  margin: 0 0 6px;
  line-height: 1.2;
}
.page-head p { margin: 0; color: var(--ink-soft); font-size: 15px; max-width: 62ch; }

.mobile-head {
  display: none;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--paper-line);
}
@media (max-width: 899px) { .mobile-head { display: flex; } }

.panel {
  background: var(--paper);
  border: 1px solid var(--paper-line);
  border-radius: var(--radius);
  padding: 20px;
  margin-bottom: 16px;
}
.panel h2 {
  font-family: 'Source Serif 4', Georgia, serif;
  font-size: 18px;
  font-weight: 600;
  margin: 0 0 4px;
}
.panel > p { margin: 0 0 12px; color: var(--ink-soft); font-size: 14.5px; }

/* §20.5: every empty state offers one relevant next action. */
.empty {
  border: 1px dashed var(--paper-line);
  border-radius: var(--radius);
  padding: 22px;
  background: #fff;
}
.empty p { margin: 0 0 14px; color: var(--ink-soft); max-width: 56ch; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 18px;
  border-radius: 8px;
  border: 1px solid transparent;
  background: var(--pen);
  color: #fff;
  font: inherit;
  font-weight: 600;
  font-size: 15px;
  cursor: pointer;
  text-decoration: none;
}
.btn:hover { background: var(--pen-deep); }
.btn.secondary { background: transparent; color: var(--pen-deep); border-color: var(--pen); }
.btn.secondary:hover { background: var(--pen-soft); }

/* Neutral status chips. §20.3: the word is the status; the tint only supports it. */
.chip {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--frame);
  color: var(--ink-soft);
  border: 1px solid var(--paper-line);
}
.chip.affirm { background: var(--pen-soft); color: var(--pen-deep); border-color: #cfe0d9; }
.chip.note { background: var(--gold-soft); color: #7a601b; border-color: #e6d5a8; }

.notice {
  border: 1px solid var(--paper-line);
  border-left: 4px solid var(--gold);
  background: var(--gold-soft);
  border-radius: 8px;
  padding: 14px 16px;
  margin-bottom: 18px;
  font-size: 14.5px;
}
.notice strong { display: block; margin-bottom: 3px; }

.people-list { list-style: none; margin: 0; padding: 0; }
.people-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 12px 0;
  border-bottom: 1px solid var(--paper-line);
}
.people-list li:last-child { border-bottom: none; }
.people-name { font-weight: 600; }
.people-meta { color: var(--ink-soft); font-size: 14px; }
.people-spacer { flex: 1 1 auto; }

.muted { color: var(--ink-soft); }
.small { font-size: 13.5px; }

/* Build-status marker. This exists so an unbuilt phase reads as unbuilt rather
   than as an empty product — §12.1 forbids showing fabricated progress or empty
   charts implying data is missing, and a working-looking view with dead buttons
   is the same lie in a different costume. Remove these as phases 2–6 land. */
.build-note {
  font-size: 13px;
  color: var(--pencil);
  border-top: 1px dashed var(--paper-line);
  margin-top: 14px;
  padding-top: 10px;
}

.disclaimer {
  font-size: 13.5px;
  color: var(--ink-soft);
  background: var(--frame);
  border-radius: 8px;
  padding: 12px 14px;
  margin-top: 16px;
}

/* Centered states — signing in, no access — sit on their own. */
.gate {
  max-width: 560px;
  margin: 8vh auto;
  padding: 32px 28px;
  background: var(--paper);
  border: 1px solid var(--paper-line);
  border-radius: var(--radius);
}
.gate h1 {
  font-family: 'Source Serif 4', Georgia, serif;
  font-size: 26px;
  margin: 0 0 10px;
}
.gate p { color: var(--ink-soft); }

.field { display: block; margin: 16px 0; }
.field span { display: block; font-size: 14px; font-weight: 600; margin-bottom: 6px; }
.field input {
  width: 100%;
  font: inherit;
  padding: 12px;
  min-height: 44px;
  border: 1px solid var(--field-line);
  border-radius: 8px;
  background: #fff;
  color: var(--ink);
}

/* §21 "error summaries and inline errors", §20.4 "show saving/saved/error
   states" — announced to screen readers via aria-live in the markup. */
.status-line { min-height: 22px; font-size: 14px; color: var(--ink-soft); margin-top: 10px; }
/* §20.3 "Do not communicate status only by color." The red is the secondary
   signal; the word is the primary one, so an error still reads as an error in
   greyscale, in high-contrast mode, and to anyone who cannot see the colour. */
.status-line[data-tone="error"] { color: #8a3b32; font-weight: 600; }
.status-line[data-tone="error"]::before { content: "Problem: "; font-weight: 700; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------------------------------------------------------------------------
   Phase 2 — onboarding, task lists, school cards, filters.
   Still no .danger / .warning / red anything: a late item is stated in words
   (§10.4) and there is no progress bar or percentage anywhere (§14.2, §3.6).
   --------------------------------------------------------------------------- */

.choice-list { display: flex; flex-direction: column; gap: 10px; }
.choice {
  display: block; width: 100%; text-align: left;
  background: #fff; border: 1px solid var(--field-line); border-radius: var(--radius);
  padding: 16px 18px; font: inherit; color: var(--ink); cursor: pointer; min-height: 44px;
}
.choice:hover { border-color: var(--pen); background: var(--pen-soft); }
.choice strong { display: block; font-size: 16px; margin-bottom: 3px; }
.choice span { display: block; font-size: 14px; color: var(--ink-soft); }

.task-list { list-style: none; margin: 0; padding: 0; }
.task-list li {
  display: flex; flex-direction: column; gap: 3px;
  padding: 12px 0; border-bottom: 1px solid var(--paper-line);
}
.task-list li:last-child { border-bottom: none; }
.task-title { font-weight: 600; color: var(--ink); text-decoration: none; }
.task-title:hover { text-decoration: underline; }
.task-title.as-text { font-weight: 500; }
.task-meta { font-size: 13.5px; color: var(--ink-soft); }
.task-note {
  font-size: 13.5px; color: var(--pencil);
  border-left: 2px solid var(--paper-line); padding-left: 10px; margin-top: 4px;
}

.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.card {
  background: #fff; border: 1px solid var(--paper-line); border-radius: var(--radius); padding: 16px;
}
.card h3 { font-family: 'Source Serif 4', Georgia, serif; font-size: 17px; margin: 0 0 6px; }
.card-meta { font-size: 13.5px; color: var(--ink-soft); margin: 0 0 4px; }

.filters { display: flex; flex-wrap: wrap; gap: 14px; margin: 0; }
/* A read-only value in a form's place (grace, §6.5.5). Deliberately NOT styled
   as a disabled input: it should read as text someone is being shown, not as a
   control that has been switched off. */
/* A checkbox and its label on one line, for the email preferences (§16.4).
   Big enough to hit on a phone without aiming. */
.field-check { display: flex; align-items: flex-start; gap: 10px; margin: 16px 0 4px; cursor: pointer; }
.field-check input { width: 20px; height: 20px; margin: 2px 0 0; flex: 0 0 auto; }
.field-check span { font-size: 16px; font-weight: 600; line-height: 1.4; }

.field-value { margin: 0; padding: 10px 0; font-size: 16px; line-height: 1.5; white-space: pre-wrap; word-break: break-word; }
/* An empty field reads "Not set", greyed by .muted (above). It used to be
   italicised as well — two signals for one fact, and italics on a UI label is
   decoration rather than meaning. */

.field.inline { margin: 0; flex: 1 1 160px; }
.field.inline select { width: 100%; font: inherit; padding: 10px; min-height: 44px;
  border: 1px solid var(--field-line); border-radius: 8px; background: #fff; color: var(--ink); }

.field select, .field textarea {
  width: 100%; font: inherit; padding: 12px; min-height: 44px;
  border: 1px solid var(--field-line); border-radius: 8px; background: #fff; color: var(--ink);
}
.field textarea { resize: vertical; }

ul.plain { list-style: disc; padding-left: 20px; margin: 10px 0; color: var(--ink-soft); font-size: 14px; }
details summary { cursor: pointer; font-size: 14px; color: var(--pen-deep); min-height: 44px; display: flex; align-items: center; }

.row-actions { margin-top: 4px; }
.link-button {
  background: none; border: none; padding: 6px 0; font: inherit; font-size: 13.5px;
  color: var(--pen-deep); text-decoration: underline; cursor: pointer; min-height: 44px;
}

/* §20.3 minimum touch target. The mobile header wordmark is a link home, and at
   its type size the clickable box was 24px tall — comfortably tappable for some
   people and not for others. Padding brings the target to 44px without changing
   how the wordmark looks. */
@media (max-width: 899px) {
  .mobile-head .brand {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding-right: 8px;
  }
}

/* ---------------------------------------------------------------------------
   Loading (UX pass, item 6)
   ---------------------------------------------------------------------------
   A page containing the single word "Loading…" is a page that has thrown away
   its own layout and will now jump when the content lands. These keep the frame
   and its rhythm in place, so the only thing that changes is the text filling
   in. Marked aria-hidden and paired with a visually-hidden live region, because
   a screen reader should hear "Loading" once, not read six grey rectangles. */
.skeleton { display: block; background: var(--frame); border-radius: 6px; height: 1em; }
.skeleton + .skeleton { margin-top: 8px; }
.skeleton.w-40 { width: 40%; }
.skeleton.w-60 { width: 60%; }
.skeleton.w-80 { width: 80%; }
.skeleton-row { padding: 12px 0; border-bottom: 1px solid var(--paper-line); }
.skeleton-row:last-child { border-bottom: none; }
@media (prefers-reduced-motion: no-preference) {
  .skeleton { animation: skeleton-pulse 1.4s ease-in-out infinite; }
  @keyframes skeleton-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
}

/* ---------------------------------------------------------------------------
   Density (UX pass, item 5)
   ---------------------------------------------------------------------------
   The old spacing treated every panel as a separate document. Related metadata
   now sits on one row, panels stop nesting their borders, and form fields stop
   being the tallest thing on the page. */
.panel { padding: 18px 20px; margin-bottom: 14px; }
.panel > h2 { font-size: 17px; margin: 0 0 10px; }
.panel .panel { border: none; padding: 0; margin: 14px 0 0; background: transparent; }
.field { margin: 12px 0; }
.field input, .field select, .field textarea { padding: 10px 12px; }
.field + .field { margin-top: 12px; }
.meta-row { display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: baseline;
  font-size: 13.5px; color: var(--ink-soft); margin: 2px 0 0; }
.meta-row > * { min-width: 0; }

/* The page heading is the NAME OF THE PAGE. A 200-character task title used to
   become the entire visual identity of the screen, so a long one is clamped to
   two lines here and shown in full in the field below it. */
.page-head h1 { font-size: 24px; line-height: 1.25; margin: 0 0 4px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; }

/* Destructive actions are separated by space rather than by a border, so they
   read as an afterthought rather than as another section. */
.danger-zone { margin-top: 28px; padding-top: 16px; border-top: 1px solid var(--paper-line); }

/* ---------------------------------------------------------------------------
   The starting-plan offer (UX pass, item 1)
   ---------------------------------------------------------------------------
   A suggestion, not a step. It sits below the user's own work, states itself in
   one line, and carries its own dismissal — so it reads as something offered
   rather than something owed. */
.offer { background: var(--pen-soft); border-color: #cfe0d9; }
.offer-head { display: flex; align-items: baseline; gap: 12px; }
.offer-head h2 { flex: 1 1 auto; margin: 0; }
.offer-dismiss { flex: none; }
.offer-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 0; }
.offer .plain { margin: 12px 0 0; }
.offer .disclaimer { margin-top: 12px; }

/* The one thing the page is for, given room to be the one thing the page is
   for. */
.primary-action { margin: 0 0 18px; }
.primary-action .btn { font-size: 16px; padding: 12px 20px; }

/* ---------------------------------------------------------------------------
   Collapsed sections (UX pass, item 3)
   ---------------------------------------------------------------------------
   <details> carrying a heading, so the disclosure is announced as a disclosure
   AND the heading stays in the document outline for anyone navigating by
   headings. The marker is left native so it keeps working in forced-colours
   mode. */
.section > summary { list-style: revert; cursor: pointer; padding: 4px 0; min-height: 44px;
  display: flex; align-items: center; }
.section > summary h2 { display: inline; font-size: 17px; margin: 0; }
.section > summary::-webkit-details-marker { color: var(--ink-soft); }
.section[open] > summary { margin-bottom: 8px; border-bottom: 1px solid var(--paper-line);
  padding-bottom: 10px; }

.back-link { margin: 0 0 10px; font-size: 14px; }
.back-link a { color: var(--pen-deep); }

/* ---------------------------------------------------------------------------
   Walkthrough and contextual hints (UX pass, item 7)
   ---------------------------------------------------------------------------
   Deliberately NOT a modal: it points at the real interface rather than
   replacing it with a slideshow, so there is nothing to trap focus in and
   nothing that blocks a returning user. */
.walkthrough { position: relative; background: var(--paper); border: 1px solid var(--pen);
  border-radius: var(--radius); padding: 12px 16px; margin: 0 0 14px; }
.walkthrough h2 { margin: 0 0 4px; font-size: 15px; }
.walkthrough p { margin: 0 0 10px; }
/* The separator lives in the MARKUP now, so it is part of the accessible name
   ("Getting started · Step 1 of 4") instead of a CSS decoration a screen reader
   never sees. */
.walkthrough-progress { font-size: 13px; font-weight: 400; color: var(--ink-soft); }

/* Off its own pages the walkthrough is one quiet line, not a card repeating
   "add schools" at somebody reading their email settings. */
.walkthrough-link { margin: 0 0 12px; font-size: 14px; }
.walkthrough-link a { color: var(--pen-deep); }
.walkthrough-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
/* Skip is always last and always to the right, whether or not the step
   also offers a Next. */
.walkthrough-actions #wt-skip { margin-left: auto; }

.hint { display: block; background: var(--gold-soft); border-radius: 8px;
  padding: 10px 12px; margin: 10px 0; font-size: 14px; }
.hint button { margin-left: 8px; }

/* "Learn more" (UX pass, item 4). The reasoning is still there for whoever
   wants it; it just is not in the way of whoever does not. */
.learn-more { margin: 8px 0 0; }
.learn-more > summary { cursor: pointer; font-size: 13.5px; color: var(--pen-deep);
  min-height: 44px; display: flex; align-items: center; }
.learn-more p { margin: 6px 0 0; color: var(--ink-soft); max-width: 62ch; }

/* ---------------------------------------------------------------------------
   Pointing at the real control (UX pass round 3)
   ---------------------------------------------------------------------------
   The walkthrough used to grow its own "Add a task" next to the page's own
   "Add a task" — two controls for one action, and the tour's was the wrong one
   to press. It now marks the product's control instead of duplicating it.

   Outline rather than a background change, so it reads as emphasis on a control
   that is otherwise unchanged, and so it survives forced-colours mode where a
   background swap would not. Offset clear of the control for the same reason
   the focus ring is. */
.wt-highlight {
  outline: 3px solid var(--gold);
  outline-offset: 3px;
  border-radius: 6px;
}
/* The focus ring must still win when the control is focused, or a keyboard user
   cannot tell where they are. */
.wt-highlight:focus-visible { outline-color: var(--focus); }
.walkthrough-here { font-size: 14px; color: var(--ink-soft); }

/* ---------------------------------------------------------------------------
   Touch targets (§20.3, desktop QA 27 Aug)
   ---------------------------------------------------------------------------
   Measured at narrow widths: task titles ~24px tall, "Back to My Work" and the
   compact walkthrough link ~17px, and Skip 44px tall but only ~28px wide. A
   44px minimum in one dimension is not a 44x44 target.

   THE WHOLE TASK ROW IS THE TARGET. Rather than padding the link until it looks
   odd, the row's single link is stretched over the row with an overlay. The
   accessibility tree is unchanged — still exactly one link per row, still named
   by the title — and there is no nested interactive content to conflict with it,
   which is why this is safe here specifically: taskRow() renders one <a> and
   nothing else clickable. */
.task-list li { position: relative; padding: 14px 0; }
.task-title { position: static; }
.task-title::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
}
/* Anything that must stay selectable sits above the overlay. Notes are the
   reason: people copy a deadline or a phone number out of them. */
.task-list li .task-note { position: relative; z-index: 2; }

/* Compact links were text-sized. They are now real targets without becoming
   buttons: inline-flex so the padding actually applies to an inline element. */
.back-link a,
.walkthrough-link a {
  display: inline-flex; align-items: center;
  min-height: 44px; padding: 0 6px; margin-left: -6px;
}

/* 44px in BOTH dimensions. min-width alone would centre a short label in a wide
   box; the padding is what makes the target match what it looks like. */
.link-button { min-width: 44px; padding: 6px 8px; }

/* On a phone the row is the target, so the title needs the room to be one. */
@media (max-width: 899px) {
  .task-list li { padding: 16px 0; }
  .task-title { font-size: 16px; line-height: 1.4; }
}

/* ===========================================================================
   Universal UX standard — the shared control system (28 Aug 2026)
   ---------------------------------------------------------------------------
   ONE interaction model for the whole Application Manager. Information reads as
   information; an editing control appears only when someone asks for it.

   The rule these classes exist to enforce: nothing that opens a large input area
   is present at rest. A property is a button showing its current value; pressing
   it opens the choices anchored beneath it. A note is text with an Edit control.
   A creation form lives in a drawer that is closed until asked for.

   Reused everywhere rather than restyled per page, so that learning one screen
   teaches all of them.
   =========================================================================== */

/* --- The action row -------------------------------------------------------
   Property buttons wrap rather than scroll or collapse into a menu: the
   standard requires every common action to stay one click away at every width,
   and a horizontal scroller hides controls off the right edge on exactly the
   screens that can least afford it. */
.actionbar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin: 0 0 18px;
}
.actionbar.tight { margin-bottom: 12px; }

/* --- Property button ------------------------------------------------------
   Label + current value + caret. The label is inside the button, not a separate
   span beside it, so a screen reader announces "Status, In progress, collapsed"
   as one control rather than stray text next to a mystery button. */
.prop {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  max-width: 100%;
  padding: 7px 11px;
  font: inherit;
  font-size: 14px;
  line-height: 1.25;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--field-line);
  border-radius: 999px;
  cursor: pointer;
  text-align: left;
}
.prop:hover { border-color: var(--pen); background: var(--pen-soft); }
.prop[aria-expanded="true"] { border-color: var(--pen); background: var(--pen-soft); }
/* Same shape, same border, same value colour as any other property button. The
   absent caret and the absent hover are what say it cannot be changed here — a
   dashed border was a second signal for that one fact, and it made one button in
   an otherwise uniform row look broken. */
.prop[disabled] { cursor: default; opacity: 1; background: var(--paper); }
.prop[disabled]:hover { border-color: var(--field-line); background: var(--paper); }
.prop .prop-label { color: var(--ink-soft); font-size: 12.5px; flex: 0 0 auto; }
.prop .prop-value {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.prop .prop-caret { flex: 0 0 auto; font-size: 10px; color: var(--ink-soft); }
.prop[disabled] .prop-caret { display: none; }
/* A property button reads the same whether or not the value is set: grey label,
   black value. "Due — No date" is a value, not an absence to be styled as one.
   Greying and italicising it made an unset field look disabled next to an
   identical control that was not, and the wording already carries the fact —
   see the note on .field-value above, which settled this once already. */

/* --- Buttons: one family, four weights ----------------------------------- */
.btn.text {
  background: transparent;
  color: var(--pen-deep);
  border-color: transparent;
  padding-left: 6px;
  padding-right: 6px;
}
.btn.text:hover { background: var(--pen-soft); border-color: transparent; }
.btn.small { padding: 7px 12px; font-size: 14px; }

/* Overflow: uncommon and destructive only. Never the only route to a frequent
   action — that is the discoverability rule, written here as a comment because
   it cannot be written as a selector. */
.btn.overflow {
  background: transparent;
  color: var(--ink-soft);
  border-color: var(--field-line);
  padding: 7px 10px;
  line-height: 1;
}
.btn.overflow:hover { background: var(--frame); color: var(--ink); border-color: var(--pen); }

/* --- Popover --------------------------------------------------------------
   Anchored to its trigger on pointer-sized screens, a bottom sheet on phones.
   640px rather than the 899px the navigation uses: a sheet sliding up from the
   bottom of a landscape tablet is a phone pattern on a screen that is not a
   phone. The nav's breakpoint answers a different question. */
.popover {
  position: absolute;
  z-index: 60;
  min-width: 220px;
  max-width: min(320px, calc(100vw - 24px));
  padding: 6px;
  background: #fff;
  border: 1px solid var(--field-line);
  border-radius: var(--radius);
  box-shadow: 0 10px 30px rgba(35, 48, 63, 0.16);
}
.popover-title {
  display: block;
  padding: 6px 10px 8px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink-soft);
}
.popover-list { list-style: none; margin: 0; padding: 0; max-height: 320px; overflow-y: auto; }
.popover-option {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 9px 10px;
  font: inherit;
  font-size: 14.5px;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  text-align: left;
}
.popover-option:hover { background: var(--pen-soft); }
.popover-option[aria-selected="true"] { font-weight: 700; }
.popover-option .tick { width: 14px; flex: 0 0 auto; color: var(--pen-deep); }
.popover-option[aria-selected="false"] .tick { visibility: hidden; }
.popover-form { padding: 8px 10px 10px; }
.popover-form .field { margin: 0 0 12px; }
.popover-actions { display: flex; gap: 8px; padding: 4px 10px 6px; }

.popover-backdrop { position: fixed; inset: 0; z-index: 55; background: transparent; }

@media (max-width: 640px) {
  .popover {
    position: fixed;
    left: 0; right: 0; bottom: 0; top: auto;
    max-width: none;
    border-radius: var(--radius) var(--radius) 0 0;
    border-bottom: 0;
    padding: 10px 10px calc(10px + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -12px 34px rgba(35, 48, 63, 0.2);
  }
  .popover-list { max-height: 52vh; }
  .popover-option { padding: 13px 12px; font-size: 16px; }
  .popover-backdrop { background: rgba(35, 48, 63, 0.28); }
}

/* --- Read-first fields ----------------------------------------------------
   A note, a title, or any other long value at rest. The edit control sits beside
   the content it edits rather than at the foot of a form, so what will change is
   never ambiguous. */
.readfield { margin: 0 0 18px; }
.readfield-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 5px;
}
.readfield-head h3 {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-soft);
}
.readfield-body {
  margin: 0;
  font-size: 15.5px;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
/* Greyed, not italicised — one signal, matching .field-value. "No note yet." is
   placeholder text rather than a note, so it stays muted; it does not also need
   a second typographic cue saying the same thing. */
.readfield-body.is-empty { color: var(--ink-soft); }
.readfield .field { margin: 0 0 10px; }
.readfield-actions { display: flex; gap: 8px; }

/* The editable page title. Reads as a heading; becomes an input on request. */
.title-edit { display: flex; align-items: flex-start; gap: 8px; }
.title-edit h1 { margin: 0; }

/* --- Drawer ---------------------------------------------------------------
   The one creation pattern. Not a full-screen modal: it keeps the list it is
   adding to visible behind it on wide screens, which is what stops "add a
   school" from feeling like leaving the page you were on. */
.drawer-backdrop {
  position: fixed;
  inset: 0;
  z-index: 70;
  background: rgba(35, 48, 63, 0.32);
  display: flex;
  justify-content: flex-end;
}
.drawer {
  width: min(440px, 100%);
  height: 100%;
  overflow-y: auto;
  background: var(--paper);
  border-left: 1px solid var(--field-line);
  padding: 22px 22px calc(22px + env(safe-area-inset-bottom, 0px));
  box-shadow: -12px 0 34px rgba(35, 48, 63, 0.18);
}
.drawer-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.drawer-head h2 { margin: 0; font-size: 20px; }
.drawer-actions { display: flex; gap: 8px; margin-top: 18px; }

@media (max-width: 640px) {
  .drawer-backdrop { align-items: flex-end; }
  .drawer {
    width: 100%;
    height: auto;
    max-height: 88vh;
    border-left: 0;
    border-top: 1px solid var(--field-line);
    border-radius: var(--radius) var(--radius) 0 0;
  }
}

/* --- Segmented control ----------------------------------------------------
   For switching between views of the same thing (Shared with me / Shared by me /
   Help requests). Real tab semantics, not styled links. */
.segmented {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 4px;
  margin: 0 0 18px;
  background: var(--frame);
  border-radius: 999px;
}
.segmented button {
  padding: 7px 14px;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-soft);
  background: transparent;
  border: 0;
  border-radius: 999px;
  cursor: pointer;
}
.segmented button:hover { color: var(--ink); }
.segmented button[aria-selected="true"] { background: #fff; color: var(--ink); box-shadow: 0 1px 2px rgba(35, 48, 63, 0.10); }

/* --- Page head with an action beside it ---------------------------------- */
.page-head.with-action {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.page-head.with-action > div { min-width: 0; }

/* --- Contextual guidance --------------------------------------------------
   Sits next to the control it describes, after the content. Never a panel above
   the user's own work. */
.hint-inline {
  margin: 6px 0 0;
  font-size: 13.5px;
  color: var(--ink-soft);
}

/* --- Focus, everywhere ---------------------------------------------------- */
.prop:focus-visible,
.popover-option:focus-visible,
.segmented button:focus-visible,
.btn.text:focus-visible,
.btn.overflow:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}
