/* ==========================================================================
   Switchboard — design system

   R5: readable in 3 seconds or it becomes wallpaper.
   R10: no guilt mechanics. Overdue is stated, never shouted.

   Motion principle: animation explains a change, it never gates one. Nothing
   here delays input, and everything collapses to instant under
   prefers-reduced-motion.
   ========================================================================== */

/* ---- Typeface ----------------------------------------------------------
   Inter, self-hosted. One 48KB variable file covering weights 100–900, latin
   subset — no external request, works offline, and nothing to break if a CDN
   does. Falls back to the system stack while it loads (font-display: swap).

   The feature settings are what stop Inter looking generic: cv11 gives the
   single-storey 'a' and humanist 'g', ss03 tidies the ampersand, and
   contextual alternates fix a handful of awkward pairs. */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---- Tokens ------------------------------------------------------------ */

:root {
  /* Spacing — 4px grid. Every margin/padding in this file uses these. */
  --s1: 0.25rem;  --s2: 0.5rem;   --s3: 0.75rem;  --s4: 1rem;
  --s5: 1.5rem;   --s6: 2rem;     --s7: 3rem;     --s8: 4rem;

  /* Type scale */
  --t-display: 1.75rem;
  --t-title:   1.25rem;
  --t-head:    1.0625rem;
  --t-body:    0.9375rem;
  --t-small:   0.8125rem;
  --t-micro:   0.6875rem;

  --radius-sm: 6px;
  --radius:    10px;
  --radius-lg: 16px;
  --radius-xl: 22px;

  /* Motion. The expo-out curve is the one that reads as "Apple": fast
     departure, long gentle settle. The spring adds a little overshoot for
     things that appear. */
  --ease-out:    cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
  --fast:   140ms;
  --normal: 260ms;
  --slow:   420ms;

  /* Dark is the default: this lives on a monitor all day. */
  color-scheme: dark;

  --bg:          #0a0b0e;
  --bg-elev:     #121419;
  --surface:     rgba(255, 255, 255, 0.038);
  --surface-2:   rgba(255, 255, 255, 0.065);
  --surface-hi:  rgba(255, 255, 255, 0.095);
  --border:      rgba(255, 255, 255, 0.085);
  --border-hi:   rgba(255, 255, 255, 0.16);

  --text:   #d3d6dc;   /* softened from #f2f3f5 — pure near-white on #0a0b0e strains the eyes */
  --text-2: rgba(211, 214, 220, 0.68);
  --text-3: rgba(211, 214, 220, 0.42);

  --accent:      #0a84ff;
  --accent-soft: rgba(10, 132, 255, 0.16);
  --ok:          #30d158;
  --warn:        #ffd60a;
  --bad:         #ff453a;

  /* P0: warm and bright enough to be unmissable, never alarming (R10). */
  --p0:      #ff9f0a;
  --p0-soft: rgba(255, 159, 10, 0.13);
  --p0-line: rgba(255, 159, 10, 0.42);

  --shadow-1: 0 1px 2px rgba(0,0,0,0.3);
  --shadow-2: 0 4px 16px -4px rgba(0,0,0,0.45);
  --shadow-3: 0 12px 40px -8px rgba(0,0,0,0.55);

  --topbar-h: 3.25rem;
}

@media (prefers-color-scheme: light) {
  :root {
    color-scheme: light;

    --bg:          #f5f5f7;
    --bg-elev:     #ffffff;
    --surface:     #ffffff;
    --surface-2:   rgba(0, 0, 0, 0.035);
    --surface-hi:  rgba(0, 0, 0, 0.055);
    --border:      rgba(0, 0, 0, 0.09);
    --border-hi:   rgba(0, 0, 0, 0.18);

    --text:   #1d1d1f;
    --text-2: rgba(29, 29, 31, 0.68);
    --text-3: rgba(29, 29, 31, 0.44);

    --accent:      #0071e3;
    --accent-soft: rgba(0, 113, 227, 0.1);
    --ok:          #1d9d3f;
    --bad:         #d70015;

    --p0:      #b25000;
    --p0-soft: rgba(178, 80, 0, 0.07);
    --p0-line: rgba(178, 80, 0, 0.28);

    --shadow-1: 0 1px 2px rgba(0,0,0,0.05);
    --shadow-2: 0 4px 16px -4px rgba(0,0,0,0.1);
    --shadow-3: 0 12px 40px -8px rgba(0,0,0,0.14);
  }
}

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

/* An explicit `display` on a rule beats the [hidden] attribute, which silently
   un-hides anything styled with display:block. Make hidden actually hide. */
[hidden] { display: none !important; }

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
               system-ui, Roboto, sans-serif;
  font-size: var(--t-body);
  line-height: 1.5;
  letter-spacing: -0.011em;
  font-feature-settings: 'cv11', 'ss03', 'calt' 1;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-wrap: break-word;
}

/* ---- Cross-page transitions -------------------------------------------- */
/* One declaration gives real page transitions in browsers that support it,
   and changes nothing in browsers that don't. */

@view-transition { navigation: auto; }

::view-transition-old(root) { animation: fade-out 90ms var(--ease-in-out) both; }
::view-transition-new(root) { animation: fade-up 260ms var(--ease-out) both; }

@keyframes fade-out { to { opacity: 0; } }
@keyframes fade-up {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* ---- Chrome ------------------------------------------------------------ */

.topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  gap: var(--s5);
  padding: 0 var(--s4);
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--border);
}

.brand {
  font-size: var(--t-head);
  font-weight: 600;
  letter-spacing: -0.021em;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
}

.topnav {
  display: flex;
  gap: var(--s1);
  align-items: center;
  margin-left: auto;
}

.topnav a {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  border-radius: var(--radius-sm);
  color: var(--text-2);
  text-decoration: none;
  font-size: var(--t-small);
  font-weight: 500;
  transition: color var(--fast) var(--ease-out),
              background var(--fast) var(--ease-out);
}

.topnav a:hover { color: var(--text); background: var(--surface-2); }
.topnav a.is-active { color: var(--text); background: var(--surface-hi); }

.topnav svg { width: 15px; height: 15px; flex: none; }

.badge {
  min-width: 1.15rem;
  padding: 0 var(--s1);
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: var(--t-micro);
  font-weight: 600;
  line-height: 1.15rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* Use the screen. A task list is scannable at width — it's paragraphs that
   need a narrow measure, and there aren't any here. Forms opt into
   .wrap--narrow, because a 90rem-wide text input is nobody's idea of good. */
.wrap {
  max-width: 78rem;
  margin: 0 auto;
  padding: var(--s6) var(--s6) var(--s8);
}

.wrap--narrow { max-width: 54rem; }
.wrap--wide   { max-width: 110rem; }

/* ---- Type -------------------------------------------------------------- */

h1 {
  font-size: var(--t-display);
  font-weight: 640;
  letter-spacing: -0.032em;
  line-height: 1.15;
  margin: 0;
}

h2 {
  font-size: var(--t-title);
  font-weight: 600;
  letter-spacing: -0.024em;
  margin: var(--s6) 0 var(--s3);
}

.muted { color: var(--text-2); }
.faint { color: var(--text-3); }
.tiny  { font-size: var(--t-small); }
.micro { font-size: var(--t-micro); }

.nums { font-variant-numeric: tabular-nums; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

code {
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;
  font-size: 0.86em;
  background: var(--surface-2);
  padding: 0.12em 0.4em;
  border-radius: var(--radius-sm);
  letter-spacing: 0;
}

pre {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--s4);
  overflow-x: auto;
  font-size: var(--t-small);
}

pre code { background: none; padding: 0; }

.pagehead {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s4);
  margin-bottom: var(--s5);
  flex-wrap: wrap;
}

.pagehead .sub { margin-top: var(--s1); color: var(--text-2); font-size: var(--t-small); }

/* ---- Quick add --------------------------------------------------------- */

.quickadd { position: relative; margin-bottom: var(--s5); }

.quickadd input[type="text"],
.quickadd input[type="email"],
.quickadd input[type="password"] {
  width: 100%;
  padding: var(--s3) 2.75rem var(--s3) var(--s4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  color: var(--text);
  font: inherit;
  box-shadow: var(--shadow-1);
  transition: border-color var(--fast) var(--ease-out),
              box-shadow var(--fast) var(--ease-out),
              background var(--fast) var(--ease-out);
}

.quickadd input:focus {
  outline: none;
  background: var(--bg-elev);
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-soft), var(--shadow-2);
}

.quickadd input::placeholder { color: var(--text-3); }

.quickadd .hint {
  position: absolute;
  right: var(--s3);
  top: 50%;
  transform: translateY(-50%);
  min-width: 1.4rem;
  padding: 0.1rem 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-3);
  font-size: var(--t-micro);
  text-align: center;
  pointer-events: none;
  transition: opacity var(--fast) var(--ease-out);
}

.quickadd input:focus ~ .hint { opacity: 0; }

/* Chips: the parse, made correctable. */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  padding: 0 var(--s2);
  max-height: 0;
  overflow: hidden;
  transition: max-height var(--normal) var(--ease-out),
              margin-top var(--normal) var(--ease-out);
}

.chips:not(:empty) { max-height: 8rem; margin-top: var(--s3); }

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
  padding: 0.15rem var(--s3);
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-2);
  font-size: var(--t-small);
  font-weight: 500;
  white-space: nowrap;
  animation: chip-in 260ms var(--ease-spring) both;
}

@keyframes chip-in {
  from { opacity: 0; transform: scale(0.82) translateY(3px); }
  to   { opacity: 1; transform: none; }
}

.chip--priority { color: var(--p0); border-color: var(--p0-line); background: var(--p0-soft); }
.chip--due      { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 35%, transparent); background: var(--accent-soft); }
.chip--project  { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 32%, transparent); }

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

.composer { position: relative; margin-bottom: var(--s5); }
.composer-input { position: relative; }

.composer-input input[type="text"] {
  width: 100%;
  padding: var(--s3) 2.75rem var(--s3) var(--s4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  color: var(--text);
  font: inherit;
  box-shadow: var(--shadow-1);
  transition: border-color var(--fast) var(--ease-out),
              box-shadow var(--fast) var(--ease-out),
              border-radius var(--fast) var(--ease-out),
              background var(--fast) var(--ease-out);
}

.composer-input input:focus {
  outline: none;
  background: var(--bg-elev);
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-soft), var(--shadow-2);
}

.composer.is-open .composer-input input { border-radius: var(--radius-lg); }

.composer-input .hint {
  position: absolute;
  right: var(--s3);
  top: 50%;
  transform: translateY(-50%);
  min-width: 1.4rem;
  padding: 0.1rem 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-3);
  font-size: var(--t-micro);
  text-align: center;
  pointer-events: none;
  transition: opacity var(--fast) var(--ease-out);
}

.composer.is-open .composer-input .hint { opacity: 0; }

/* The card is attached to the field, not floating over the page. */
.composer-card {
  margin-top: var(--s2);
  padding: var(--s4);
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
  transform-origin: top center;
}

/* JS collapses it; without JS the attribute is removed and it's simply open. */
.composer-card[data-collapsed] { display: none; }

.composer.is-open .composer-card {
  display: block;
  animation: card-in var(--normal) var(--ease-out) both;
}

@keyframes card-in {
  from { opacity: 0; transform: translateY(-6px) scaleY(0.97); }
}

.composer-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--s4);
}

/* Inline subtask composer — sits in the stack directly under its parent, and
   is indented so the parent/child relationship reads at a glance. */
.composer--inline {
  margin: calc(var(--s2) * -1) 0 var(--s2) var(--s6);
  animation: subtask-in var(--normal) var(--ease-out) both;
}

@keyframes subtask-in {
  from { opacity: 0; transform: translateY(-6px); }
}

.composer--inline .composer-input input[type="text"] {
  padding: var(--s2) var(--s4);
  border-radius: var(--radius);
  font-size: var(--t-small);
}

.composer--inline .composer-card {
  margin-top: var(--s1);
  padding: var(--s3);
}

.composer--inline .composer-grid { gap: var(--s3); }

.composer--inline.is-leaving {
  animation: subtask-out 160ms var(--ease-in-out) both;
  pointer-events: none;
}

@keyframes subtask-out {
  to { opacity: 0; transform: translateY(-6px); }
}

.cfield { min-width: 0; }
.cfield--wide { grid-column: 1 / -1; }

.cfield-label {
  display: block;
  margin-bottom: var(--s2);
  color: var(--text-3);
  font-size: var(--t-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.segmented {
  display: inline-flex;
  padding: 2px;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  gap: 2px;
  margin-bottom: var(--s2);
  max-width: 100%;
}

.seg {
  flex: 1;
  padding: var(--s1) var(--s3);
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--text-2);
  font: inherit;
  font-size: var(--t-small);
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--fast) var(--ease-out), color var(--fast) var(--ease-out);
}

.seg:hover { color: var(--text); }
.seg:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.seg[aria-pressed="true"], .seg.is-on {
  background: var(--bg-elev);
  color: var(--text);
  box-shadow: var(--shadow-1);
}

.seg[data-priority="0"][aria-pressed="true"] { color: var(--p0); }

.input--sm { padding: var(--s1) var(--s2); font-size: var(--t-small); }

.composer-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  margin-top: var(--s4);
  padding-top: var(--s3);
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}

.composer-actions code {
  font-size: 0.95em;
  padding: 0.05em 0.3em;
}

/* ---- Autocomplete ------------------------------------------------------ */

.suggestwrap { position: relative; }

.suggest {
  position: absolute;
  left: 0; right: 0; top: calc(100% + 4px);
  z-index: 30;
  max-height: 13rem;
  overflow-y: auto;
  background: var(--bg-elev);
  border: 1px solid var(--border-hi);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
  animation: fade-up 160ms var(--ease-out) both;
}

.suggest-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  width: 100%;
  padding: var(--s2) var(--s3);
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: var(--t-small);
  text-align: left;
  cursor: pointer;
}

.suggest-item:hover,
.suggest-item.is-active { background: var(--accent-soft); }

.suggest-item .uses { color: var(--text-3); font-size: var(--t-micro); }
.suggest-item .ns { color: var(--text-3); }

/* ---- Projects rail ----------------------------------------------------- */

.rail {
  display: flex;
  gap: var(--s2);
  overflow-x: auto;
  padding-bottom: var(--s2);
  margin-bottom: var(--s4);
  scrollbar-width: thin;
}

.rail::-webkit-scrollbar { height: 5px; }
.rail::-webkit-scrollbar-thumb { background: var(--border-hi); border-radius: 3px; }

.railcard {
  flex: none;
  min-width: 8.5rem;
  max-width: 13rem;
  padding: var(--s2) var(--s3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--fast) var(--ease-out),
              background var(--fast) var(--ease-out),
              transform var(--fast) var(--ease-out);
}

.railcard:hover {
  text-decoration: none;
  border-color: var(--border-hi);
  background: var(--surface-2);
  transform: translateY(-1px);
}

.railcard .rname {
  display: block;
  font-size: var(--t-small);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.railcard .rmeta { display: block; margin-top: 1px; color: var(--text-3); font-size: var(--t-micro); }
.railcard--new { border-style: dashed; color: var(--text-2); display: grid; place-items: center; min-width: 6.5rem; }

/* A rail card is a drop target for tasks. */
.railcard.is-drop {
  border-color: var(--accent);
  background: var(--accent-soft);
  transform: scale(1.03);
}

/* ---- The stack --------------------------------------------------------- */

.stack { display: flex; flex-direction: column; gap: var(--s2); }

.band {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin: var(--s5) 0 var(--s1);
  color: var(--text-3);
  font-size: var(--t-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
}

.band::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.band:first-child { margin-top: 0; }

/* A task row. A plain card — evenly rounded, quiet. The sticky-note treatment
   belongs to Notes (entities), not to tasks; see .sticky below. */

.note {
  --i: 0;
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: var(--s3);
  /* Right padding reserves the hover "+" slot so the P# tag never shifts. */
  padding: var(--s3) 2.5rem var(--s3) var(--s4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: inherit;
  /* Depth falloff, capped so the bottom of a long list stays legible. */
  opacity: calc(1 - min(var(--i) * 0.02, 0.26));
  transition: opacity var(--fast) var(--ease-out),
              border-color var(--fast) var(--ease-out),
              background var(--fast) var(--ease-out),
              transform var(--fast) var(--ease-out),
              box-shadow var(--fast) var(--ease-out);
}

.note:hover {
  opacity: 1;
  background: var(--surface-2);
  border-color: var(--border-hi);
  box-shadow: var(--shadow-2);
}

/* P0 keeps the amber tint — no sticky corner, just a warmer card. */
.note--p0 {
  opacity: 1;
  background: linear-gradient(var(--p0-soft), var(--p0-soft)), var(--surface);
  border-color: var(--p0-line);
}

/* Subtasks sit indented under their parent, with a short connector. */
.note--sub {
  margin-left: var(--s6);
}

.note--sub::before {
  content: "";
  position: absolute;
  left: calc(var(--s4) * -1);
  top: 50%;
  width: var(--s3);
  height: 1px;
  background: var(--border-hi);
}

.note--done { opacity: 0.4; }
.note--done .note-title { text-decoration: line-through; text-decoration-thickness: 1px; }

/* Entrance stagger — the list assembles rather than snapping in. */
.stack-animate .note {
  animation: note-in var(--slow) var(--ease-out) both;
  animation-delay: calc(min(var(--i), 12) * 26ms);
}

@keyframes note-in {
  from { opacity: 0; transform: translateY(10px) scale(0.995); }
}

/* Leaving: collapse the row so the next item slides up (§7.1). */
.note.is-leaving {
  animation: note-out 320ms var(--ease-in-out) both;
  pointer-events: none;
}

@keyframes note-out {
  40%  { opacity: 0; transform: translateX(14px); }
  100% { opacity: 0; transform: translateX(14px);
         max-height: 0; padding-top: 0; padding-bottom: 0;
         margin-top: calc(var(--s2) * -1); border-width: 0; }
}

.note-check { flex: none; padding-top: 1px; }
.note-check form { display: block; line-height: 0; }

.check {
  position: relative;
  width: 1.3rem;
  height: 1.3rem;
  border-radius: 50%;
  border: 1.5px solid var(--text-3);
  background: transparent;
  cursor: pointer;
  padding: 0;
  display: grid;
  place-items: center;
  transition: border-color var(--fast) var(--ease-out),
              background var(--fast) var(--ease-out),
              transform var(--fast) var(--ease-spring);
}

.check svg {
  width: 12px; height: 12px;
  stroke: #fff;
  stroke-width: 2.75;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
  opacity: 0;
  stroke-dasharray: 18;
  stroke-dashoffset: 18;
  transition: opacity var(--fast) var(--ease-out);
}

.check:hover { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 16%, transparent); transform: scale(1.08); }
.check:active { transform: scale(0.92); }

.check.is-checked {
  background: var(--ok);
  border-color: var(--ok);
}

.check.is-checked svg {
  opacity: 1;
  animation: draw-check 300ms var(--ease-out) both;
}

@keyframes draw-check { to { stroke-dashoffset: 0; } }

.note--p0 .check { border-color: var(--p0); }

/* ---- Sticky notes — for Notes (entities), never for tasks --------------- */

.sticky {
  --pad:      #22375c;
  --pad-edge: #2b4570;
  --pad-gum:  #1a2b49;

  position: relative;
  display: block;
  padding: var(--s5) var(--s4) var(--s4);
  font-size: var(--t-body);
  background:
    /* the gummed strip along the top, fading out rather than a hard band */
    linear-gradient(var(--pad-gum), transparent) top / 100% 2.25rem no-repeat,
    linear-gradient(155deg, var(--pad-edge), var(--pad));
  border-radius: 1px;                 /* square, like real paper */
  color: inherit;
  text-decoration: none;
  /* Stuck at the top, curling free at the bottom.
     The top edge keeps the "correct" width because that is where the gum
     holds it flat; the sides splay outward as they fall away from the wall,
     so the sheet is narrowest at the top and widest at the bottom. clip-path
     removes box-shadow, hence drop-shadow. */
  clip-path: polygon(
    1.2% 0, 98.8% 0,
    99.4% 34%, 100% 68%, 100% 100%,
    0 100%, 0 68%, 0.6% 34%
  );
  filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.34))
          drop-shadow(0 10px 18px rgba(0, 0, 0, 0.26));
  transition: transform var(--fast) var(--ease-out), filter var(--fast) var(--ease-out);
}

.sticky:hover {
  transform: translateY(-2px);
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.42))
          drop-shadow(0 16px 26px rgba(0, 0, 0, 0.3));
  text-decoration: none;
}

/* ---- Curled corners ----------------------------------------------------
   A real pad does not peel evenly, so the curl is dealt out rather than
   applied to everything: roughly a third curl bottom-right, a third
   bottom-left, a third lie flat. partials/sticky.php stamps .sticky--curl-r
   / --curl-l / nothing from the ref, so a given note keeps the same curl
   every render — a curl that moved on reload would read as a glitch. */

.sticky--curl-r,
.sticky--curl-l { position: relative; }

.sticky--curl-r {
  clip-path: polygon(
    1.2% 0, 98.8% 0,
    99.4% 34%, 100% 68%, 100% 88%,
    88% 100%, 0 100%, 0 68%, 0.6% 34%
  );
}

.sticky--curl-l {
  clip-path: polygon(
    1.2% 0, 98.8% 0,
    99.4% 34%, 100% 68%, 100% 100%,
    12% 100%, 0 88%, 0 68%, 0.6% 34%
  );
}

/* The lifted triangle itself: a shaded wedge under the cut corner, so the
   corner reads as folded rather than sliced off. */
.sticky--curl-r::after,
.sticky--curl-l::after {
  content: "";
  position: absolute;
  bottom: 0;
  width: 12%;
  aspect-ratio: 1;
  pointer-events: none;
}

.sticky--curl-r::after {
  right: 0;
  background: linear-gradient(315deg, var(--pad-gum) 0 48%, transparent 48%);
}

.sticky--curl-l::after {
  left: 0;
  background: linear-gradient(45deg, var(--pad-gum) 0 48%, transparent 48%);
}

.sticky-open {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.sticky-title {
  display: block;
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.35;
  color: var(--text);
}

.sticky-body {
  margin-top: var(--s2);
  font-size: var(--t-body);
  color: var(--text-2);
  line-height: 1.55;
  /* Sticky notes are a glance, not a document — the full text is one click. */
  display: -webkit-box;
  -webkit-line-clamp: 8;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.sticky-meta {
  display: flex;
  gap: var(--s2);
  align-items: center;
  flex-wrap: wrap;
  margin-top: var(--s3);
  font-size: var(--t-micro);
  color: var(--text-3);
}

/* What a note is attached to, along the bottom. Without these a wall of
   stickies gives no clue which project or company any of them belong to. */
.sticky-tags {
  display: flex;
  gap: var(--s1);
  flex-wrap: wrap;
  align-items: center;
  margin-top: var(--s3);
  padding-top: var(--s2);
  border-top: 1px solid rgba(255, 255, 255, 0.10);
}

.stag {
  padding: 0.05rem var(--s2);
  border-radius: var(--radius-sm);
  border: 1px solid var(--tc, rgba(255, 255, 255, 0.16));
  background: rgba(255, 255, 255, 0.07);
  color: var(--text-2);
  font-size: var(--t-micro);
  font-weight: 500;
  white-space: nowrap;
  line-height: 1.5;
}

.stag--type { text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700; }
.stag--project { border-color: rgba(255, 255, 255, 0.3); color: var(--text); }

@media (prefers-color-scheme: light) {
  .sticky-tags { border-top-color: rgba(0, 0, 0, 0.12); }
  .stag {
    border-color: var(--tc, rgba(0, 0, 0, 0.16));
    background: rgba(255, 255, 255, 0.45);
    color: #333;
  }
  .stag--project { border-color: rgba(0, 0, 0, 0.3); color: #111; }
}

/* Type tints, so a decision doesn't look like a shopping note. */
.sticky--decision { --pad: #4a3a12; --pad-edge: #63501a; --pad-gum: #392c0d; }
.sticky--idea     { --pad: #123a30; --pad-edge: #174c3e; --pad-gum: #0d2b24; }
.sticky--doc      { --pad: #2f2a4d; --pad-edge: #3d3663; --pad-gum: #241f3b; }

@media (prefers-color-scheme: light) {
  .sticky {
    --pad:      #bcd8ff;
    --pad-edge: #d6e9ff;
    --pad-gum:  #a9c9f5;
  }
  .sticky--decision { --pad: #ffe6ab; --pad-edge: #fff2cf; --pad-gum: #f0d295; }
  .sticky--idea     { --pad: #b9ecd8; --pad-edge: #d6f6e9; --pad-gum: #a2ddc6; }
  .sticky--doc      { --pad: #ddd8fb; --pad-edge: #ebe8ff; --pad-gum: #c8c1f0; }
  .sticky { filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.16)); }
  .sticky:hover { filter: drop-shadow(0 6px 12px rgba(0, 0, 0, 0.2)); }
}

.stickygrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--s4);
  align-items: start;
}

/* Expanded, a note takes the whole row — the editor needs the width, and the
   note you're writing on should dominate the ones you aren't. */
.sticky.is-expanded {
  grid-column: 1 / -1;
  clip-path: none;                 /* straight edges while editing */
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
  filter: none;
}

.sticky.is-expanded .sticky-body { -webkit-line-clamp: unset; }
.sticky.is-expanded .sticky-tags { display: none; }

.sticky-edit {
  margin-top: var(--s4);
  padding-top: var(--s4);
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  animation: fade-up var(--normal) var(--ease-out) both;
}

.sticky-edit .field { margin-bottom: var(--s3); }
.sticky-edit .panel-head { display: none; }

/* Inputs on a colored pad need their own contrast. */
.sticky-edit .input {
  background: rgba(0, 0, 0, 0.22);
  border-color: rgba(255, 255, 255, 0.18);
  color: var(--text);
}

@media (prefers-color-scheme: light) {
  .sticky-edit { border-top-color: rgba(0, 0, 0, 0.16); }
  .sticky-edit .input { background: rgba(255, 255, 255, 0.7); border-color: rgba(0, 0, 0, 0.18); }
}

/* ---- Priority tag ------------------------------------------------------
   Fixed width and always the last item in the flow, so it lines up down the
   whole list regardless of what else a row happens to carry. */
.prio {
  flex: none;
  align-self: center;
  width: 2.1rem;
  text-align: center;
  padding: 0.1rem 0;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.03em;
  font-variant-numeric: tabular-nums;
}

.prio--0 { color: #ffd08a; background: rgba(255, 159, 10, 0.18); border-color: rgba(255, 159, 10, 0.42); }
.prio--1 { color: #9ec9ff; background: rgba(10, 132, 255, 0.18); border-color: rgba(10, 132, 255, 0.40); }
.prio--2 { color: var(--text-2); background: rgba(255, 255, 255, 0.07); border-color: rgba(255, 255, 255, 0.10); }
.prio--3 { color: var(--text-3); background: transparent; border-color: rgba(255, 255, 255, 0.09); }

@media (prefers-color-scheme: light) {
  .prio--0 { color: #8a4b00; background: rgba(255, 159, 10, 0.20); border-color: rgba(180, 100, 0, 0.35); }
  .prio--1 { color: #12508f; background: rgba(0, 113, 227, 0.14); border-color: rgba(0, 113, 227, 0.30); }
  .prio--2 { color: var(--text-2); background: rgba(0, 0, 0, 0.05); border-color: rgba(0, 0, 0, 0.09); }
  .prio--3 { color: var(--text-3); background: transparent; border-color: rgba(0, 0, 0, 0.08); }
}

.note-body { flex: 1; min-width: 0; }

.note-title {
  display: block;
  color: var(--text);
  text-decoration: none;
  line-height: 1.4;
}

.note-title:hover { text-decoration: none; color: var(--accent); }

.note-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
  margin-top: var(--s1);
  font-size: var(--t-small);
  color: var(--text-3);
}

/* Overdue is stated, never shouted (R10). */
.overdue   { color: var(--text-2); }
.due-today { color: var(--accent); font-weight: 500; }

.orgstripe {
  position: absolute;
  left: 0; top: var(--s3); bottom: var(--s3);
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--border);
}

.tag {
  padding: 0.05rem var(--s2);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text-2);
  font-size: var(--t-small);
  text-decoration: none;
  transition: background var(--fast) var(--ease-out);
}

a.tag:hover { background: var(--surface-hi); text-decoration: none; }

/* ---- Desk cards -------------------------------------------------------- */

.deskgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: var(--s2);
  margin-bottom: var(--s6);
}

.deskcard {
  position: relative;
  display: block;
  padding: var(--s3) var(--s4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: inherit;
  text-decoration: none;
  overflow: hidden;
  transition: transform var(--fast) var(--ease-out),
              border-color var(--fast) var(--ease-out),
              box-shadow var(--fast) var(--ease-out),
              background var(--fast) var(--ease-out);
}

.deskcard::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--c, var(--border));
}

.deskcard:hover {
  transform: translateY(-2px);
  background: var(--surface-2);
  border-color: var(--border-hi);
  box-shadow: var(--shadow-2);
  text-decoration: none;
}

.deskcard .n {
  display: block;
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.deskcard .l {
  display: block;
  margin-top: 1px;
  font-size: var(--t-small);
  color: var(--text-2);
}

.deskcard .p0dot {
  display: inline-block;
  width: 5px; height: 5px;
  margin-left: var(--s1);
  border-radius: 50%;
  background: var(--p0);
  vertical-align: middle;
}

/* ---- Pills ------------------------------------------------------------- */

.pills {
  display: flex;
  gap: var(--s1);
  flex-wrap: wrap;
  margin-bottom: var(--s4);
  padding: var(--s1);
  background: var(--surface-2);
  border-radius: 999px;
  width: fit-content;
  max-width: 100%;
}

.pill {
  padding: var(--s1) var(--s3);
  border-radius: 999px;
  color: var(--text-2);
  text-decoration: none;
  font-size: var(--t-small);
  font-weight: 500;
  white-space: nowrap;
  transition: color var(--fast) var(--ease-out),
              background var(--fast) var(--ease-out);
}

.pill:hover { color: var(--text); text-decoration: none; }

.pill.is-active {
  background: var(--bg-elev);
  color: var(--text);
  box-shadow: var(--shadow-1);
}

/* ---- Split layout: tasks left, notes right ----------------------------- */

.split {
  display: grid;
  /* Columns fill the wrap exactly, so the composer, desk cards, and lists all
     share one left and right edge down the whole page. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 31rem);
  gap: var(--s6);
  align-items: start;
}

.split--single { grid-template-columns: minmax(0, 1fr); }

.split-main, .split-side { min-width: 0; }

/* One column below this — a 19rem sidebar next to a task list is unusable. */
@media (max-width: 60rem) {
  .split { grid-template-columns: minmax(0, 1fr); }
  .split-side { margin-top: var(--s5); }
}

.stickygrid--narrow { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: var(--s3); }

/* A few notes get the full width of their column and read as notes; a wall of
   them needs the density more than the size. The switch is at six, chosen
   because that is roughly where a single column stops fitting on screen. */
.stickygrid--few  { grid-template-columns: 1fr; gap: var(--s3); }
.stickygrid--many { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s3); }

@media (max-width: 40rem) {
  .stickygrid--many { grid-template-columns: 1fr; }
}

/* ---- View controls ----------------------------------------------------- */

.viewbar {
  display: flex;
  gap: var(--s3);
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: var(--s4);
}

.pill-label {
  padding: var(--s1) var(--s2);
  color: var(--text-3);
  font-size: var(--t-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Sub-grouping heading inside a band. Quieter than the band above it, so the
   time axis still reads as primary. */
.subband {
  display: flex;
  align-items: center;
  gap: var(--s2);
  margin: var(--s3) 0 var(--s1);
  padding-left: var(--s1);
  color: var(--text-2);
  font-size: var(--t-small);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.subband .n {
  padding: 0 var(--s1);
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-3);
  font-size: var(--t-micro);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

/* ---- Recent strip ------------------------------------------------------ */

.recent {
  margin-top: var(--s7);
  padding-top: var(--s4);
  border-top: 1px solid var(--border);
  font-size: var(--t-small);
  color: var(--text-3);
}

.recent-line {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  padding: var(--s1) 0;
}

.recent-line .sig { color: var(--text-3); font-size: 0.6rem; }
.recent-line .sig--3 { color: var(--p0); }

/* ---- Empty states — pleasant to return to after neglect (R10) ----------- */

.empty {
  padding: var(--s8) var(--s4);
  text-align: center;
  color: var(--text-3);
  animation: fade-up var(--slow) var(--ease-out) both;
}

.empty strong {
  display: block;
  margin-bottom: var(--s1);
  color: var(--text-2);
  font-size: var(--t-head);
  font-weight: 500;
  letter-spacing: -0.015em;
}

.empty svg {
  width: 34px; height: 34px;
  margin-bottom: var(--s3);
  stroke: var(--text-3);
  stroke-width: 1.25;
  fill: none;
  opacity: 0.6;
}

/* ---- Tables ------------------------------------------------------------ */

.health {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  margin: var(--s3) 0;
  font-size: var(--t-body);
}

.health th, .health td {
  text-align: left;
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--border);
  font-weight: 400;
  vertical-align: top;
}

.health tr:last-child th, .health tr:last-child td { border-bottom: none; }
.health th { color: var(--text-2); width: 11rem; white-space: nowrap; }

.ok { color: var(--ok); } .warn { color: var(--warn); } .bad { color: var(--bad); }

/* ---- Buttons ----------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s4);
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  font-size: var(--t-small);
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--fast) var(--ease-out),
              border-color var(--fast) var(--ease-out),
              transform var(--fast) var(--ease-out);
}

.btn:hover { background: var(--surface-hi); border-color: var(--border-hi); text-decoration: none; }
.btn:active { transform: scale(0.97); }

.btn--primary { background: var(--accent); border-color: transparent; color: #fff; }
.btn--primary:hover { background: color-mix(in srgb, var(--accent) 88%, #fff); }

.btn--danger { color: var(--bad); }
.btn--danger:hover { background: color-mix(in srgb, var(--bad) 14%, transparent); border-color: color-mix(in srgb, var(--bad) 40%, transparent); }

.btn--ghost { background: transparent; border-color: transparent; color: var(--text-2); }
.btn--ghost:hover { background: var(--surface-2); color: var(--text); }

.prose { line-height: 1.65; color: var(--text-2); }
.prose h2 { color: var(--text); }

/* ---- Forms ------------------------------------------------------------- */

.field { margin-bottom: var(--s4); }

.field > label {
  display: block;
  margin-bottom: var(--s1);
  color: var(--text-2);
  font-size: var(--t-small);
  font-weight: 500;
}

.field .help { margin-top: var(--s1); color: var(--text-3); font-size: var(--t-small); }

/* Build-time rationale, shown only when dev_notes is on. Visually set apart
   so it never reads as instructions to a normal user. */
.help-spec {
  color: var(--accent);
  opacity: 0.75;
  font-style: italic;
}

.help--spec { margin-top: var(--s1); }

.input,
select.input,
textarea.input {
  width: 100%;
  padding: var(--s2) var(--s3);
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font: inherit;
  transition: border-color var(--fast) var(--ease-out),
              box-shadow var(--fast) var(--ease-out);
}

.input:focus, select.input:focus, textarea.input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

textarea.input { min-height: 7rem; resize: vertical; line-height: 1.55; font-family: inherit; }

/* Native <option> popups don't inherit the control's colours in every browser,
   so the inbox "file into" dropdown rendered as stark system black-and-white.
   Theme the options explicitly to match the app. */
select.input option,
select.input optgroup {
  background: var(--bg-elev);
  color: var(--text);
}

/* A colour input renders its swatch *inside* the element, so the generic
   .input background and padding were covering it — the chosen colour only
   appeared once the OS picker opened. Strip both and let the swatch fill. */
.input[type="color"] {
  padding: 3px;
  height: 2.1rem;
  cursor: pointer;
  background: var(--surface-2);
}

.input--sm[type="color"] { height: 1.85rem; }

.input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.input[type="color"]::-webkit-color-swatch { border: none; border-radius: 4px; }
.input[type="color"]::-moz-color-swatch { border: none; border-radius: 4px; }

select.input {
  appearance: none;
  padding-right: var(--s6);
  background-image: linear-gradient(45deg, transparent 50%, var(--text-3) 50%),
                    linear-gradient(135deg, var(--text-3) 50%, transparent 50%);
  background-position: calc(100% - 17px) 52%, calc(100% - 12px) 52%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  cursor: pointer;
}

.field-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: var(--s3);
}

.card {
  padding: var(--s4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: var(--s4);
}

.formactions {
  display: flex;
  align-items: center;
  gap: var(--s2);
  flex-wrap: wrap;
  margin-top: var(--s5);
  padding-top: var(--s4);
  border-top: 1px solid var(--border);
}

.formactions .spacer { flex: 1; }

/* Inline "file this into a project" control on Inbox rows. */
.filebox { display: inline-flex; align-items: center; gap: var(--s1); }

.filebox select {
  padding: 0.05rem var(--s2);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-2);
  font: inherit;
  font-size: var(--t-small);
  cursor: pointer;
  max-width: 11rem;
}

.filebox select:focus { outline: none; border-color: var(--accent); color: var(--text); }

.notice {
  padding: var(--s3) var(--s4);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface-2);
  font-size: var(--t-small);
  margin-bottom: var(--s4);
}

.notice--warn { border-color: color-mix(in srgb, var(--warn) 40%, transparent); background: color-mix(in srgb, var(--warn) 10%, transparent); }
.notice--bad  { border-color: color-mix(in srgb, var(--bad) 40%, transparent);  background: color-mix(in srgb, var(--bad) 10%, transparent); }

/* ---- Toast ------------------------------------------------------------- */

.toast {
  position: fixed;
  left: 50%;
  bottom: var(--s5);
  z-index: 100;
  transform: translate(-50%, 1.5rem);
  padding: var(--s2) var(--s4);
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 999px;
  box-shadow: var(--shadow-3);
  font-size: var(--t-small);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--normal) var(--ease-out),
              transform var(--normal) var(--ease-spring);
}

.toast.is-visible { opacity: 1; transform: translate(-50%, 0); }

/* Live-update pill — "N new — show". Stays until clicked (reloads the page),
   sits above the toast, and is calm rather than nagging (R10). */
.pulse-pill {
  position: fixed;
  left: 50%;
  bottom: var(--s5);
  z-index: 101;
  transform: translate(-50%, 1.5rem);
  padding: var(--s2) var(--s4);
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 999px;
  box-shadow: var(--shadow-3);
  font: inherit;
  font-size: var(--t-small);
  font-weight: 500;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--normal) var(--ease-out),
              transform var(--normal) var(--ease-spring);
}
.pulse-pill.is-on { opacity: 1; transform: translate(-50%, 0); }
.pulse-pill:hover { filter: brightness(1.08); }
.pulse-pill:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* ---- Side panel editor -------------------------------------------------
   The list shifts left and the editor slides in beside it, so you keep your
   place in the stack instead of navigating away and back. Without JS the same
   URL (/t/{ref}) is a normal full page — the panel is an enhancement. */

.panel {
  position: fixed;
  top: var(--topbar-h);
  right: 0;
  bottom: 0;
  width: min(30rem, 100vw);
  z-index: 60;
  overflow-y: auto;
  padding: var(--s5) var(--s5) var(--s8);
  background: var(--bg-elev);
  border-left: 1px solid var(--border);
  box-shadow: var(--shadow-3);
  transform: translateX(100%);
  visibility: hidden;
  transition: transform var(--normal) var(--ease-out),
              visibility 0s linear var(--normal);
}

.panel.is-open {
  transform: none;
  visibility: visible;
  transition: transform var(--normal) var(--ease-out), visibility 0s;
}

/* While the editor is open everything EXCEPT the row being edited dims.
 *
 * This dims siblings rather than laying a scrim over the page. A scrim can't
 * work here: `body.panel-open .wrap` carries a transform, which creates a
 * stacking context, so no z-index on the row inside it can climb above a
 * fixed overlay — the scrim would grey out the very task you're editing, and
 * would also swallow clicks into its title field.
 */
body.is-editing-card .topbar,
body.is-editing-card .composer,
body.is-editing-card .deskgrid,
body.is-editing-card .rail,
body.is-editing-card .viewbar,
body.is-editing-card .recent,
body.is-editing-card .pagehead,
body.is-editing-card .band,
body.is-editing-card .subband {
  opacity: 0.3;
  transition: opacity var(--normal) var(--ease-out);
}

/* Dim only leaf cards, never a container of the one being edited: opacity
   creates a compositing context, so a child can never be more opaque than its
   parent — dimming .split-side faded the very note inside it. */
body.is-editing-card .note:not(.is-editing),
body.is-editing-card .sticky:not(.is-expanded) {
  opacity: 0.25;
  transition: opacity var(--normal) var(--ease-out);
}

/* The row under edit keeps its normal color and gains a focus ring. */
.note.is-editing {
  opacity: 1 !important;
  background: var(--surface-2);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft), var(--shadow-3);
}

.note--p0.is-editing {
  background: linear-gradient(var(--p0-soft), var(--p0-soft)), var(--surface-2);
}

/* Title edited in place. Looks like the title until you're in it. */
.note-title-edit {
  display: block;
  width: 100%;
  padding: 1px var(--s2);
  margin: -1px calc(var(--s2) * -1);
  background: var(--bg-elev);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  color: var(--text);
  font: inherit;
  line-height: 1.4;
  resize: none;
  overflow: hidden;
}

.note-title-edit:focus { outline: none; box-shadow: 0 0 0 3px var(--accent-soft); }

.panel-scrim.is-open { opacity: 1; visibility: visible; transition: opacity var(--normal) var(--ease-out), visibility 0s; }

.panel-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s3);
  margin-bottom: var(--s4);
}

.panel-close {
  flex: none;
  width: 1.9rem; height: 1.9rem;
  display: grid; place-items: center;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text-2);
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
  transition: background var(--fast) var(--ease-out), color var(--fast) var(--ease-out);
}

.panel-close:hover { background: var(--surface-hi); color: var(--text); }

.panel .field { margin-bottom: var(--s3); }
.panel h1 { font-size: var(--t-title); }

@media (max-width: 62rem) {
  /* Not enough room to push anything aside — become a sheet. */
  body.panel-open .wrap { transform: none; }
  .panel { width: 100%; }
}

/* ---- Drag and drop -----------------------------------------------------
   Reordering by dragging is a pointer affordance; every change it makes is
   also reachable from the editor, so nothing is drag-only. */

.note[draggable="true"] { cursor: grab; }
.note.is-dragging { opacity: 0.4; cursor: grabbing; }

.band.is-drop {
  color: var(--accent);
}

.band.is-drop::after { background: var(--accent); }

/* Explicit drop targets, visible only during a drag. */
.dragbar {
  position: fixed;
  left: 50%;
  bottom: var(--s5);
  z-index: 70;
  display: flex;
  gap: var(--s5);
  align-items: center;
  padding: var(--s3) var(--s4);
  background: color-mix(in srgb, var(--bg-elev) 92%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border: 1px solid var(--border-hi);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-3);
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, 1.25rem);
  transition: opacity var(--normal) var(--ease-out),
              transform var(--normal) var(--ease-spring),
              visibility 0s linear var(--normal);
  flex-wrap: wrap;
  max-width: calc(100vw - 2rem);
}

body.is-dragging-task .dragbar {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition: opacity var(--normal) var(--ease-out),
              transform var(--normal) var(--ease-spring),
              visibility 0s;
}

.dragbar-group { display: flex; align-items: center; gap: var(--s1); }

.dragbar-label {
  margin-right: var(--s1);
  color: var(--text-3);
  font-size: var(--t-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.drop {
  padding: var(--s1) var(--s3);
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-2);
  font: inherit;
  font-size: var(--t-small);
  font-weight: 500;
  white-space: nowrap;
  pointer-events: auto;
  transition: background var(--fast) var(--ease-out),
              border-color var(--fast) var(--ease-out),
              transform var(--fast) var(--ease-out),
              color var(--fast) var(--ease-out);
}

.drop.is-drop {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  transform: scale(1.1);
}

.drop[data-priority="0"].is-drop { background: var(--p0); border-color: var(--p0); }

/* Drag-to-file: orgs in the bar, projects in a popover that opens upward while
   you drag over the org (see openOrg() in switchboard.js — CSS :hover can't be
   trusted mid-drag). */
.drop-org { position: relative; display: inline-flex; }

.drop-caret { margin-left: 0.15em; font-size: 0.8em; opacity: 0.6; }

.drop-org.is-open .drop-org-head {
  background: var(--accent-soft);
  border-color: var(--border-hi);
  color: var(--text);
}

.drop-projects {
  position: absolute;
  bottom: calc(100% + var(--s2));
  left: 50%;
  z-index: 71;
  display: flex;
  flex-direction: column;
  gap: var(--s1);
  min-width: max-content;
  max-height: 45vh;
  overflow-y: auto;
  padding: var(--s2);
  background: color-mix(in srgb, var(--bg-elev) 96%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border: 1px solid var(--border-hi);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translate(-50%, 0.5rem);
  transition: opacity var(--fast) var(--ease-out),
              transform var(--fast) var(--ease-spring),
              visibility 0s linear var(--fast);
}

.drop-org.is-open .drop-projects {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translate(-50%, 0);
  transition: opacity var(--fast) var(--ease-out),
              transform var(--fast) var(--ease-spring),
              visibility 0s;
}

.drop-project { text-align: left; }
.drop-project.is-sub::before { content: "— "; color: var(--text-3); }

@media (hover: none) {
  /* HTML5 drag-and-drop doesn't fire on touch; the bar would be dead weight. */
  .dragbar { display: none; }
}

/* Quick-add-subtask affordance, revealed on hover.
   Absolutely positioned so it never occupies flow space — otherwise rows that
   have one and rows that don't would align their P# tags differently, which
   is exactly the jitter this replaced. */
.note-add {
  position: absolute;
  right: var(--s2);
  top: 50%;
  transform: translateY(-50%);
  width: 1.6rem; height: 1.6rem;
  display: grid; place-items: center;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-3);
  cursor: pointer;
  opacity: 0;
  font-size: 1rem;
  line-height: 1;
  transition: opacity var(--fast) var(--ease-out),
              background var(--fast) var(--ease-out),
              color var(--fast) var(--ease-out);
}

.note:hover .note-add,
.note-add:focus-visible { opacity: 1; }

.note-add:hover { background: var(--surface-hi); color: var(--text); border-color: var(--border); }

@media (hover: none) { .note-add { opacity: 1; } }

/* ---- Inline editing ----------------------------------------------------
   Title and body become writable *where they already are*, styled to match
   the surrounding text, so clicking a card doesn't relocate your attention.
   The remaining fields drop into a panel underneath. Nothing about this
   shifts the page. */

.inline-title,
.inline-body {
  display: block;
  width: 100%;
  padding: var(--s1) var(--s2);
  margin-left: calc(var(--s2) * -1);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text);
  font: inherit;
  resize: none;
  overflow: hidden;
  transition: background var(--fast) var(--ease-out), border-color var(--fast) var(--ease-out);
}

.inline-title {
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.35;
}

.inline-body {
  margin-top: var(--s1);
  font-size: var(--t-body);
  line-height: 1.55;
  color: var(--text-2);
}

.inline-title:hover,
.inline-body:hover { background: rgba(127, 127, 127, 0.08); }

.inline-title:focus,
.inline-body:focus {
  outline: none;
  background: rgba(127, 127, 127, 0.10);
  border-color: var(--accent);
}

.inline-body::placeholder { color: var(--text-3); }

/* The rest of the fields, tucked under the text you were reading. */
.editfields {
  margin-top: var(--s4);
  padding-top: var(--s4);
  border-top: 1px solid var(--border);
  animation: fade-up var(--normal) var(--ease-out) both;
}

.editfields .composer-grid { gap: var(--s3); }

/* A task card being edited: grows in place, stays lit, doesn't move anything. */
.note.is-editing {
  opacity: 1 !important;
  display: block;
  padding: var(--s4);
  background: var(--bg-elev);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft), var(--shadow-3);
  cursor: default;
}

.note.is-editing .note-check,
.note.is-editing .prio,
.note.is-editing .note-add,
.note.is-editing .note-body { display: none; }

.note--p0.is-editing {
  background: linear-gradient(var(--p0-soft), var(--p0-soft)), var(--bg-elev);
}

/* Inputs on a colored sticky need their own contrast. */
.sticky .editfields { border-top-color: rgba(255, 255, 255, 0.16); }
.sticky .editfields .input,
.sticky .editfields .segmented {
  background: rgba(0, 0, 0, 0.22);
  border-color: rgba(255, 255, 255, 0.18);
  color: var(--text);
}

@media (prefers-color-scheme: light) {
  .sticky .editfields { border-top-color: rgba(0, 0, 0, 0.16); }
  .sticky .editfields .input,
  .sticky .editfields .segmented {
    background: rgba(255, 255, 255, 0.72);
    border-color: rgba(0, 0, 0, 0.16);
  }
}

/* Close button and save indicator, pinned to the top-right of the editor. */
.inline-head {
  position: absolute;
  top: var(--s2);
  right: var(--s2);
  display: flex;
  align-items: center;
  gap: var(--s2);
  z-index: 2;
}

.savestate {
  color: var(--text-3);
  font-size: var(--t-micro);
  opacity: 0;
  transition: opacity var(--fast) var(--ease-out);
}

.savestate.is-on { opacity: 1; }
.savestate.is-error { color: var(--bad); opacity: 1; }

.inline-close {
  width: 1.6rem;
  height: 1.6rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text-2);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  transition: background var(--fast) var(--ease-out), color var(--fast) var(--ease-out);
}

.inline-close:hover { background: var(--surface-hi); color: var(--text); }

.note.is-editing, .sticky.is-expanded { position: relative; }
.inline-edit { position: relative; }

/* Leave room for the close button so a long title doesn't run under it. */
.inline-title { padding-right: 3.5rem; }

/* ---- Sortable admin rows ----------------------------------------------- */

.sortlist { display: flex; flex-direction: column; gap: var(--s2); margin-bottom: var(--s6); }

.sortrow {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  transition: border-color var(--fast) var(--ease-out),
              background var(--fast) var(--ease-out),
              opacity var(--fast) var(--ease-out);
}

.sortrow:hover { border-color: var(--border-hi); }
.sortrow.is-dragging { opacity: 0.4; }

/* Where the dragged row would land. */
.sortrow.is-over { border-color: var(--accent); box-shadow: 0 -2px 0 var(--accent) inset; }

.sortrow-main {
  /* Grid, not flex-wrap: the Edit button keeps its own column so a row with
     many project tags can't push it onto a second line. */
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s3);
  padding: var(--s3) var(--s4);
}

.sortrow-body {
  display: flex;
  align-items: center;
  gap: var(--s2);
  flex-wrap: wrap;
  min-width: 0;
}

.draghandle {
  color: var(--text-3);
  cursor: grab;
  font-size: 0.8rem;
  letter-spacing: -2px;
  user-select: none;
}

.sortrow.is-dragging .draghandle { cursor: grabbing; }

.swatch {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  flex: none;
  border: 1px solid rgba(127, 127, 127, 0.35);
}

.sortrow-tags { display: flex; gap: var(--s1); flex-wrap: wrap; }

/* The settings form, opened under its row. */
.rowedit-slot { padding: 0 var(--s4) var(--s4); }

.rowedit {
  position: relative;
  padding-top: var(--s3);
  border-top: 1px solid var(--border);
  animation: fade-up var(--normal) var(--ease-out) both;
}

.rowedit .inline-head { top: var(--s2); right: 0; }

/* ---- Scroll reveal ----------------------------------------------------- */

.reveal { opacity: 0; transform: translateY(12px); }

.reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity var(--slow) var(--ease-out),
              transform var(--slow) var(--ease-out);
}

/* ---- Responsive -------------------------------------------------------- */

@media (max-width: 40rem) {
  :root { --t-display: 1.5rem; }

  .wrap { padding: var(--s4) var(--s3) var(--s8); }
  .topbar { gap: var(--s3); padding: 0 var(--s3); }
  .topnav { gap: 0; }
  .topnav a { padding: var(--s2); }
  .topnav .label { display: none; }   /* icons only on small screens */
  .deskgrid { grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr)); }

  /* Comfortable touch targets. */
  .check { width: 1.5rem; height: 1.5rem; }
  .note { padding: var(--s4) var(--s4); }
  .pills { width: 100%; overflow-x: auto; flex-wrap: nowrap; }
}

@media (hover: none) {
  /* No hover on touch — don't leave rows stuck in a hover state. */
  .note:hover { transform: none; box-shadow: none; }
  .deskcard:hover { transform: none; }
}

/* ---- Reduced motion ---------------------------------------------------- */
/* Motion is decoration here; every animation has an instant equivalent. */

@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;
  }
  .reveal { opacity: 1; transform: none; }
  @view-transition { navigation: none; }
}

/* ===========================================================================
   Rich text (Phase 5)
   ---------------------------------------------------------------------------
   Two surfaces sharing one look: `.md` renders stored markdown read-only, and
   `.rte` is the same thing made editable. They deliberately use the same type
   scale — if formatting shifts when you click into a note, you stop trusting
   what you are seeing.
   ========================================================================= */

.md,
.rte {
  line-height: 1.65;
  color: var(--text-2);
  overflow-wrap: anywhere;
}

.md > *:first-child,
.rte > *:first-child { margin-top: 0; }
.md > *:last-child,
.rte > *:last-child { margin-bottom: 0; }

.md h1, .rte h1,
.md h2, .rte h2,
.md h3, .rte h3,
.md h4, .rte h4 {
  color: var(--text);
  font-weight: 620;
  letter-spacing: -0.01em;
  margin: var(--s4) 0 var(--s2);
  line-height: 1.3;
}

.md h1, .rte h1 { font-size: 1.35rem; }
.md h2, .rte h2 { font-size: 1.15rem; }
.md h3, .rte h3 { font-size: 1.02rem; }
.md h4, .rte h4 { font-size: 0.95rem; color: var(--text-2); }

.md p, .rte p { margin: 0 0 var(--s3); }

.md ul, .rte ul,
.md ol, .rte ol { margin: 0 0 var(--s3); padding-left: 1.35rem; }
.md li, .rte li { margin: 0.15rem 0; }

/* Only the checkbox items lose their marker. A mixed list — some bullets,
   some checkboxes — is normal, and blanking the marker on the whole list
   leaves the plain items looking like orphaned text. */
.md ul.tasklist, .rte ul.tasklist { padding-left: 1.35rem; }
.md ul.tasklist li[data-task], .rte ul.tasklist li[data-task] {
  display: flex;
  gap: var(--s2);
  align-items: baseline;
  list-style: none;
  margin-left: -1.2rem;
}
.md ul.tasklist input, .rte ul.tasklist input { margin: 0; flex: none; }
.md ul.tasklist li[data-checked="true"],
.rte ul.tasklist li[data-checked="true"] { color: var(--text-3); text-decoration: line-through; }

.md blockquote, .rte blockquote {
  margin: 0 0 var(--s3);
  padding: var(--s1) 0 var(--s1) var(--s3);
  border-left: 2px solid var(--border-hi);
  color: var(--text-3);
}

.md code, .rte code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.88em;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  padding: 0.1em 0.35em;
}

.md pre, .rte pre {
  margin: 0 0 var(--s3);
  padding: var(--s3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow-x: auto;
}
.md pre code, .rte pre code {
  background: none;
  padding: 0;
  font-size: 0.86rem;
  line-height: 1.55;
  white-space: pre;
}

.md hr, .rte hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: var(--s4) 0;
}

.md a, .rte a { color: var(--accent); text-decoration: none; }
.md a:hover, .rte a:hover { text-decoration: underline; }

.md del, .rte del { color: var(--text-3); }

/* ---- The editable surface ---- */

.rte-host { position: relative; }

.rte {
  min-height: 6rem;
  padding: var(--s3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  outline: none;
  transition: border-color var(--fast), background var(--fast);
}

.rte:focus {
  border-color: var(--accent);
  background: var(--bg-elev);
}

/* Placeholder only on a genuinely empty document — an empty <p><br></p>. */
.rte:empty::before,
.rte > p:only-child:empty::before {
  content: attr(data-placeholder);
  color: var(--text-3);
  pointer-events: none;
}

.rte ul.tasklist input { cursor: pointer; }

.rte-hint {
  margin: var(--s1) 0 0;
  opacity: 0;
  transition: opacity var(--fast);
}
.rte-host:focus-within .rte-hint { opacity: 1; }

.rte-hint kbd {
  font-family: inherit;
  font-size: 0.9em;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.05em 0.3em;
}

/* ---- The "/" menu ---- */

.rte-menu {
  position: absolute;
  z-index: 40;
  min-width: 15rem;
  max-height: 17rem;
  overflow-y: auto;
  padding: var(--s1);
  background: var(--bg-elev);
  border: 1px solid var(--border-hi);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
  animation: rte-pop var(--fast) ease-out;
}

@keyframes rte-pop {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}

.rte-menu-item {
  display: flex;
  flex-direction: column;
  gap: 1px;
  width: 100%;
  padding: var(--s2) var(--s3);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.rte-menu-item small { color: var(--text-3); font-size: 0.8rem; }
.rte-menu-item:hover,
.rte-menu-item.is-active { background: var(--accent-soft); }

/* Compact variant for the in-card inline editors. */
.rte.inline-body { min-height: 3.5rem; background: none; border-color: transparent; padding: var(--s2); }
.rte.inline-body:focus { background: var(--surface); border-color: var(--border); }

@media (prefers-reduced-motion: reduce) {
  .rte-menu { animation: none; }
}

/* ===========================================================================
   Docs (Phase 6, §14)
   ========================================================================= */

.split-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--s3);
  margin-bottom: var(--s5);
}

a.doccard {
  display: block;
  padding: var(--s3);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--fast), transform var(--fast), background var(--fast);
}

a.doccard strong { display: block; color: var(--text); }
a.doccard .help { margin-top: var(--s1); }

a.doccard:hover {
  border-color: var(--border-hi);
  background: var(--surface-2);
  transform: translateY(-1px);
}

/* Docs are long-form: cap the measure so lines stay readable. */
article.md { max-width: 46rem; }
article.md table { width: 100%; border-collapse: collapse; margin: 0 0 var(--s3); }
article.md th, article.md td {
  text-align: left;
  padding: var(--s2) var(--s3);
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
article.md th { color: var(--text); font-weight: 560; }

@media (prefers-reduced-motion: reduce) {
  a.doccard:hover { transform: none; }
}

/* ---- Account switcher --------------------------------------------------- */

.accountswitch { position: relative; }

.accountswitch > summary {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  border-radius: var(--radius-sm);
  cursor: pointer;
  list-style: none;
  color: var(--text-2);
}
.accountswitch > summary::-webkit-details-marker { display: none; }
.accountswitch > summary:hover { background: var(--surface-2); color: var(--text); }
.accountswitch[open] > summary { background: var(--surface-2); color: var(--text); }
.accountswitch > summary svg { width: 1.05rem; height: 1.05rem; flex: none; }

.accountmenu {
  position: absolute;
  top: calc(100% + var(--s2));
  right: 0;
  z-index: 60;
  min-width: 14rem;
  padding: var(--s1);
  background: var(--bg-elev);
  border: 1px solid var(--border-hi);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
}

.accountmenu form { margin: 0; }

.accountmenu-row {
  display: block;
  width: 100%;
  padding: var(--s2) var(--s3);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.accountmenu-row small { display: block; color: var(--text-3); font-size: 0.8rem; }
.accountmenu-row:hover { background: var(--accent-soft); }
/* The one you are already using is a label, not a button. */
.accountmenu-row.is-active { cursor: default; background: var(--surface-2); }

.accountmenu-link {
  display: block;
  padding: var(--s2) var(--s3);
  border-radius: var(--radius-sm);
  color: var(--text-2);
  font-size: 0.88rem;
  text-decoration: none;
}
.accountmenu-link:hover { background: var(--surface-2); color: var(--text); }
.accountmenu-link:first-of-type { margin-top: var(--s1); border-top: 1px solid var(--border); padding-top: var(--s3); }

/* ===========================================================================
   Sign in
   ---------------------------------------------------------------------------
   Its own layout — this page renders without the app chrome, and it is the
   first thing anyone sees.
   ========================================================================= */

.signin-page {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: var(--s4);
  /* A soft wash rather than flat fill, so the card has something to sit on. */
  background:
    radial-gradient(120% 90% at 50% -10%, var(--accent-soft), transparent 60%),
    var(--bg);
}

.signin { width: 100%; max-width: 22.5rem; }

.signin-card {
  padding: var(--s6) var(--s5) var(--s5);
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  animation: signin-in var(--slow) var(--ease-out) both;
}

@keyframes signin-in {
  from { opacity: 0; transform: translateY(8px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}

.signin-brand {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin-bottom: var(--s2);
}

.signin-brand h1 {
  margin: 0;
  font-size: 1.3rem;
  letter-spacing: -0.02em;
}

.signin-mark {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  flex: none;
  border-radius: var(--radius);
  background: var(--accent);
  color: #fff;
}
.signin-mark svg { width: 1.25rem; height: 1.25rem; }

.signin-sub {
  margin: 0 0 var(--s5);
  color: var(--text-3);
  font-size: 0.9rem;
}

.signin-error {
  margin-bottom: var(--s4);
  padding: var(--s3);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--bad) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--bad) 38%, transparent);
  color: var(--bad);
  font-size: 0.88rem;
}

.signin-form { display: grid; gap: var(--s4); }

.signin-field { display: grid; gap: var(--s2); }
.signin-field > span {
  font-size: 0.82rem;
  color: var(--text-3);
  letter-spacing: 0.01em;
}

.signin-code {
  font-size: 1.35rem;
  letter-spacing: 0.35em;
  text-align: center;
}

.signin-go {
  width: 100%;
  justify-content: center;
  padding: var(--s3);
  font-size: 0.95rem;
}

.signin-alt {
  text-align: center;
  font-size: 0.85rem;
  color: var(--text-3);
  text-decoration: none;
}
.signin-alt:hover { color: var(--text-2); }

.signin-foot {
  margin: var(--s4) 0 0;
  text-align: center;
  font-size: 0.78rem;
  color: var(--text-3);
}
.signin-foot code { font-size: 0.95em; }

@media (prefers-reduced-motion: reduce) {
  .signin-card { animation: none; }
}
