/* ============================================================
   Homestead

   The visual brief is a well-kept maintenance binder: paper, ink, ruled
   lines, tabs down the side. Nothing decorative, because the two moments
   this app is opened are "what do I need to buy" and "it's dark and the
   water has stopped".

   Colour carries exactly one meaning: how urgent something is. Everything
   else is paper and ink, so that the one red box on a page is the one you
   are meant to read first.
   ============================================================ */

:root {
  --paper:      #faf8f4;   /* warm off-white */
  --paper-2:    #ffffff;
  --paper-3:    #f2eee7;   /* recessed areas, table stripes */
  --rule:       #e2dcd2;   /* hairlines */
  --rule-2:     #cfc7b9;
  --ink:        #1c1a17;
  --ink-2:      #55504a;   /* secondary text */
  --ink-3:      #8b857c;   /* labels, timestamps */
  --accent:     #2f5d50;   /* deep green — buttons, links */
  --accent-2:   #3d7565;

  /* Urgency. Muted on purpose: a page of saturated badges is harder to scan
     than a page of quiet ones, and the only thing that should catch the eye
     across a room is a problem. */
  --st-ok:       #2f6b4f;
  --st-watch:    #96690f;
  --st-down:     #9b2c2c;
  --st-seasonal: #5c6b7a;
  --st-quiet:    #79736b;

  --danger:     #9b2c2c;
  --danger-bg:  #fbf1f0;
  --warn-bg:    #faf4e6;

  --radius:     4px;       /* barely rounded — paper, not plastic */
  --shadow:     0 1px 2px rgba(28,26,23,.05), 0 8px 24px rgba(28,26,23,.06);
  --shadow-lg:  0 2px 8px rgba(28,26,23,.08), 0 24px 60px rgba(28,26,23,.16);

  --serif: 'Fraunces', Georgia, 'Times New Roman', serif;
  --sans:  'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;

  --sidebar-w: 232px;
}

* { box-sizing: border-box; }

/* The `hidden` attribute has to beat every layout rule in this file. A class
   selector like `.drawer { display: flex }` outranks the user agent's
   `[hidden] { display: none }` — without this line the gate, the drawer, the
   scrim and the toast all render stacked on the page from the moment it loads.
   Everything that appears and disappears does so by toggling `hidden`, so this
   one rule is load-bearing. */
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { font-family: var(--serif); font-weight: 500; margin: 0; letter-spacing: -0.01em; }

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

/* ---- Sign-in gate -------------------------------------------------------- */

.gate {
  min-height: 100vh; display: grid; place-items: center;
  padding: 24px; background: var(--paper);
}
.gate-card {
  width: 100%; max-width: 380px; background: var(--paper-2);
  border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 34px 30px; box-shadow: var(--shadow);
}
.gate-sub { color: var(--ink-3); font-size: 14px; margin: 0 0 22px; }
.gate-error {
  color: var(--danger); font-size: 13px; margin: 0;
  background: var(--danger-bg); padding: 8px 10px; border-radius: var(--radius);
}
.gate-note { color: var(--ink-2); font-size: 13px; margin: 0; }

/* "or use your password" — a rule with the words sitting in the gap. */
.gate-or {
  display: flex; align-items: center; gap: 10px; margin: 16px 0;
  font-size: 12px; color: var(--ink-3); text-transform: uppercase; letter-spacing: .06em;
}
.gate-or::before, .gate-or::after { content: ''; flex: 1; height: 1px; background: var(--rule); }

.mode-badge {
  display: inline-block; margin: 8px 0 0; font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .1em;
  color: #8a3b6b; background: #f7edf3; border: 1px solid #e8d3e0;
  padding: 2px 8px; border-radius: 999px;
}

.passkey-row .meta { font-variant-numeric: tabular-nums; }

.wordmark {
  font-family: var(--serif); font-size: 25px; font-weight: 600;
  letter-spacing: -0.02em; margin: 0 0 4px;
}
.wordmark span { font-weight: 400; color: var(--ink-3); }

/* ---- App frame ----------------------------------------------------------- */

.app { display: grid; grid-template-columns: var(--sidebar-w) 1fr; min-height: 100vh; }

.sidebar {
  background: var(--paper-2); border-right: 1px solid var(--rule);
  padding: 22px 0 16px; display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
  /* Grid children default to a min-width of their content. Without this the
     horizontally-scrolling nav below widens the whole column on a phone, and
     the page scrolls sideways. */
  min-width: 0;
}
.brand { padding: 0 20px 20px; }
.property-name { font-size: 13px; color: var(--ink-3); margin: 6px 0 0; }
.property-switch { margin-top: 10px; }
.property-switch select {
  width: 100%; font: inherit; font-size: 13px; padding: 5px 7px;
  border: 1px solid var(--rule); border-radius: var(--radius); background: var(--paper);
}

.nav { display: flex; flex-direction: column; gap: 1px; padding: 0 12px; flex: 1; }
.nav-item {
  padding: 8px 12px; border-radius: var(--radius); font-size: 14px;
  color: var(--ink-2); display: flex; align-items: center; gap: 8px;
}
.nav-item:hover { background: var(--paper-3); text-decoration: none; color: var(--ink); }
.nav-item.active { background: var(--accent); color: #fff; }
/* The count of things that are late, sitting on the nav item that leads to
   them. The only number in the chrome, so it means only one thing. */
.nav-item .badge {
  margin-left: auto; background: var(--danger); color: #fff;
  font-size: 11px; font-weight: 600; border-radius: 999px; padding: 1px 7px;
  font-variant-numeric: tabular-nums;
}
.nav-item.active .badge { background: rgba(255,255,255,.28); }

.sidebar-foot {
  padding: 14px 20px 0; margin-top: 12px; border-top: 1px solid var(--rule);
  display: flex; flex-direction: column; gap: 4px;
}
.who { font-size: 12px; color: var(--ink-3); overflow-wrap: anywhere; }

.main { min-width: 0; padding: 32px 40px 80px; }
.view { max-width: 1080px; }

/* ---- Page furniture ------------------------------------------------------ */

.page-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 16px; margin-bottom: 22px; flex-wrap: wrap;
}
.page-head h2 { font-size: 27px; }
.page-head .sub { color: var(--ink-3); font-size: 14px; margin: 2px 0 0; }
.head-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

.section-title {
  font-size: 12px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--ink-3); margin: 30px 0 10px; font-family: var(--sans); font-weight: 600;
}
.section-title:first-child { margin-top: 0; }

.backlink { font-size: 13px; color: var(--ink-3); display: inline-block; margin-bottom: 8px; }

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

.btn {
  font: inherit; font-size: 14px; padding: 7px 14px; cursor: pointer;
  background: var(--paper-2); color: var(--ink); border: 1px solid var(--rule-2);
  border-radius: var(--radius);
}
.btn:hover { background: var(--paper-3); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-2); }
.btn-danger { color: var(--danger); border-color: #e4cccc; }
.btn-danger:hover { background: var(--danger-bg); }
.btn-block { width: 100%; }
.btn-sm { font-size: 13px; padding: 5px 10px; }
.btn:disabled { opacity: .5; cursor: default; }

.icon-btn {
  background: none; border: 0; font-size: 22px; line-height: 1; cursor: pointer;
  color: var(--ink-3); padding: 4px 8px; border-radius: var(--radius);
}
.icon-btn:hover { background: var(--paper-3); color: var(--ink); }

.linkish {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--accent); font: inherit; font-size: 13px; text-align: left;
}
.linkish:hover { text-decoration: underline; }

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

.stack { display: flex; flex-direction: column; gap: 14px; }
.field { display: flex; flex-direction: column; gap: 5px; }
.field > span, .field > label {
  font-size: 12px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3); font-weight: 600;
}
.field input, .field select, .field textarea {
  font: inherit; padding: 8px 10px; border: 1px solid var(--rule-2);
  border-radius: var(--radius); background: var(--paper-2); color: var(--ink); width: 100%;
  /* Native inputs and selects size their own content box differently, which
     left a select three pixels shorter than the input beside it. Pinning the
     line height makes the two boxes agree. */
  line-height: 1.45;
}

/* ---- Dropdowns -----------------------------------------------------------
   The native chevron is drawn by the platform, in the platform's own colour
   and position — which puts it somewhere different in every browser and
   ignores the padding set above. Drawing our own is the only way it lands in
   the same place every time, and the only way it can be the same ink as the
   rest of the form. */
.field select, .toolbar select, .property-switch select {
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238b857c' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  background-size: 10px 6px;
  padding-right: 32px;      /* room for it, so a long option never runs under */
}
.property-switch select { background-position: right 8px center; padding-right: 26px; }
.toolbar select { background-position: right 9px center; padding-right: 28px; }
/* Firefox keeps a focus ring inside the box; we draw our own on :focus. */
.field select:-moz-focusring { color: transparent; text-shadow: 0 0 0 var(--ink); }

/* Two controls under one caption — "Every [6] [months]". */
.field-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.field textarea { resize: vertical; min-height: 72px; line-height: 1.45; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent);
}
.field .hint { font-size: 12px; color: var(--ink-3); text-transform: none; letter-spacing: 0; font-weight: 400; }

/* ---- Reveal a password ---------------------------------------------------
   A word, not an eye: the icon is a coin-flip between "showing" and "will
   show" in every app that uses it, and this one has room for four letters. */
.pw-wrap { position: relative; display: block; }
.pw-wrap input { padding-right: 62px; }
.pw-peek {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  font: inherit; font-size: 12px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-3);
  background: none; border: 0; cursor: pointer; padding: 4px 6px;
  border-radius: var(--radius);
}
.pw-peek:hover { color: var(--ink); background: var(--paper-3); }
.pw-peek[aria-pressed="true"] { color: var(--accent); }

/* ---- Avatars -------------------------------------------------------------
   An emoji if the person chose one, otherwise their initials on a colour
   derived from the account id — so everybody has one and nobody has to. */
.avatar {
  display: inline-grid; place-items: center; flex: 0 0 auto;
  width: 32px; height: 32px; border-radius: 50%;
  font-size: 13px; font-weight: 600; line-height: 1;
  font-family: var(--sans); letter-spacing: .02em;
  user-select: none;
}
.avatar.emoji { font-size: 17px; }
.avatar-sm { width: 22px; height: 22px; font-size: 10px; }
.avatar-sm.emoji { font-size: 12px; }
.avatar-lg { width: 46px; height: 46px; font-size: 17px; }
.avatar-lg.emoji { font-size: 24px; }

.who-row { display: flex; align-items: center; gap: 9px; min-width: 0; }
.who-row .who-name { font-size: 13px; color: var(--ink-2); overflow-wrap: anywhere; }
.row .avatar { margin-right: 2px; }

/* ---- Formatting bar ------------------------------------------------------
   Three buttons over a long-text field. The field still holds plain text: the
   markers stay visible while you edit, and are rendered when it is read back.
   Each button shows the letter in the face it applies, so it needs no label. */
.rt-bar { display: flex; gap: 4px; }
.rt-bar button {
  font: inherit; font-size: 13px; line-height: 1; width: 30px; height: 26px;
  cursor: pointer; color: var(--ink-2); padding: 0;
  background: var(--paper-2); border: 1px solid var(--rule-2);
  border-radius: var(--radius);
}
.rt-bar button:hover { background: var(--paper-3); color: var(--ink); }
.rt-bar button:active { background: var(--rule); }
.rt-sep { width: 1px; background: var(--rule); margin: 2px 3px; }
.rt-op { font-size: 12px !important; }
.rt-b { font-weight: 700; }
.rt-i { font-family: var(--serif); font-style: italic; }
.rt-u { text-decoration: underline; }

/* ---- Rendered lists ------------------------------------------------------
   These sit inside white-space: pre-wrap containers, so the markup is emitted
   with no newlines between the tags — any that were there would show up as
   blank lines. The spacing below is the list's own, not the container's. */
.prose ul, .prose ol, .cbody ul, .cbody ol,
.step-body ul, .step-body ol, .meta ul, .meta ol {
  margin: 4px 0; padding-left: 24px; white-space: normal;
}
.prose li, .cbody li, .step-body li, .meta li { margin: 3px 0; }
/* A nested list hugs its parent item rather than opening a gap. */
.prose li > ul, .prose li > ol, .cbody li > ul, .cbody li > ol,
.step-body li > ul, .step-body li > ol { margin: 3px 0 0; }
.prose ol, .cbody ol, .step-body ol, .meta ol { list-style: decimal; }
.prose ul, .cbody ul, .step-body ul, .meta ul { list-style: disc; }
.prose li::marker, .cbody li::marker { color: var(--ink-3); }

/* Underline is the one that can read as a link. Inside prose and callouts it
   never is, so it is given a slightly softer rule than a link's. */
.prose u, .callout u, .cbody u, .step-body u, .step-outcome u, .meta u {
  text-decoration-color: var(--rule-2);
  text-underline-offset: 2px;
}

.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.field-row-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; }

.check { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--ink-2); }
.check input { width: auto; }

.form-error {
  color: var(--danger); font-size: 13px; background: var(--danger-bg);
  padding: 8px 10px; border-radius: var(--radius); margin: 0;
}

/* ---- Toolbar (search + filters) ------------------------------------------ */

.toolbar { display: flex; gap: 8px; margin-bottom: 18px; flex-wrap: wrap; align-items: center; }
.toolbar input[type="search"] {
  font: inherit; padding: 7px 11px; border: 1px solid var(--rule-2);
  border-radius: var(--radius); background: var(--paper-2); min-width: 220px; flex: 1 1 220px;
}
.toolbar select {
  font: inherit; font-size: 14px; padding: 7px 9px;
  border: 1px solid var(--rule-2); border-radius: var(--radius); background: var(--paper-2);
}

/* ---- Stat tiles ---------------------------------------------------------- */

.tiles {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px; background: var(--rule); border: 1px solid var(--rule);
  border-radius: var(--radius); overflow: hidden; margin-bottom: 26px;
}
.tile { background: var(--paper-2); padding: 16px 18px; }
.tile .label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-3); font-weight: 600;
}
.tile .value { font-family: var(--serif); font-size: 27px; line-height: 1.1; margin-top: 4px; }
.tile .foot { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.tile.alert .value { color: var(--danger); }
.tile.warn .value  { color: var(--st-watch); }

/* ---- Callouts ------------------------------------------------------------
   The emergency note on a system and the warning on a runbook. Deliberately
   the loudest thing on any page they appear on, because they are the reason
   somebody opened it. */

.callout {
  border-left: 3px solid var(--rule-2); background: var(--paper-3);
  padding: 12px 14px; border-radius: 0 var(--radius) var(--radius) 0; margin-bottom: 16px;
}
.callout h4 {
  font-family: var(--sans); font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); margin-bottom: 5px;
}
.callout p, .callout .cbody { margin: 0; font-size: 14px; white-space: pre-wrap; line-height: 1.5; }
.callout.danger { border-left-color: var(--danger); background: var(--danger-bg); }
.callout.danger h4 { color: var(--danger); }
.callout.warn { border-left-color: var(--st-watch); background: var(--warn-bg); }
.callout.warn h4 { color: var(--st-watch); }

/* ---- Status pills -------------------------------------------------------- */

.pill {
  display: inline-flex; align-items: center; gap: 5px; font-size: 12px;
  padding: 2px 9px; border-radius: 999px; white-space: nowrap; font-weight: 500;
}
.pill::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }

.pill.ok       { color: var(--st-ok);       background: #edf4f0; }
.pill.watch    { color: var(--st-watch);    background: #f8f2e6; }
.pill.down     { color: var(--st-down);     background: var(--danger-bg); }
.pill.seasonal { color: var(--st-seasonal); background: #eef1f4; }

.pill.overdue     { color: var(--danger);    background: var(--danger-bg); }
.pill.due         { color: var(--st-watch);  background: #f8f2e6; }
.pill.later       { color: var(--st-ok);     background: #edf4f0; }
.pill.unscheduled { color: var(--st-quiet);  background: var(--paper-3); }

.pill.critical  { color: var(--danger);   background: var(--danger-bg); }
.pill.important { color: var(--st-watch); background: #f8f2e6; }
.pill.routine   { display: none; }   /* the default needs no badge */

/* A small type label with no urgency attached: system kind, device category. */
.tag {
  display: inline-block; font-size: 11px; text-transform: uppercase;
  letter-spacing: .06em; color: var(--ink-3); background: var(--paper-3);
  padding: 2px 7px; border-radius: var(--radius); font-weight: 600;
}

/* ---- Cards (systems) ----------------------------------------------------- */

.sys-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 14px; }
.sys-card {
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--radius);
  padding: 15px 16px; display: flex; flex-direction: column; gap: 7px;
  cursor: pointer; transition: box-shadow .12s ease, transform .12s ease;
}
.sys-card:hover { box-shadow: var(--shadow); transform: translateY(-1px); }
.sys-card .top { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
/* The card is a flex column, which would otherwise stretch the kind tag to
   the full width and turn a label into a bar. */
.sys-card .tag { align-self: flex-start; }
.sys-card h3 { font-size: 17px; line-height: 1.25; }
.sys-card .where { font-size: 13px; color: var(--ink-3); }
.sys-card .foot {
  display: flex; gap: 12px; font-size: 12px; color: var(--ink-3);
  border-top: 1px solid var(--rule); padding-top: 8px; margin-top: auto;
  font-variant-numeric: tabular-nums;
}
.sys-card .foot .late { color: var(--danger); font-weight: 600; }

/* ---- Rows (tasks, runbooks, logs, contacts) ------------------------------
   A list of rows rather than a table: on a phone a table either scrolls
   sideways or shrinks to unreadable, and every one of these lists is read on
   a phone at least as often as at a desk. */

.rows { border: 1px solid var(--rule); border-radius: var(--radius); background: var(--paper-2); }
.row {
  display: flex; align-items: baseline; gap: 12px; padding: 11px 14px;
  border-bottom: 1px solid var(--rule); cursor: pointer;
}
.row:last-child { border-bottom: 0; }
.row:hover { background: var(--paper-3); }
.row.flat { cursor: default; }
.row.flat:hover { background: transparent; }
.row .main-col { flex: 1; min-width: 0; }
.row .title { font-size: 15px; }
.row .meta { font-size: 12.5px; color: var(--ink-3); margin-top: 1px; }
.row .right { text-align: right; font-size: 13px; white-space: nowrap; }
.row .right .when { font-variant-numeric: tabular-nums; }
.row .right .overdue { color: var(--danger); font-weight: 600; }
.row .actions { display: flex; gap: 6px; }

/* "11 steps" on a task row — a quiet promise that the job is written down. */
.has-steps { color: var(--accent); }

.group-head {
  display: flex; align-items: baseline; gap: 8px; margin: 26px 0 8px;
}
.group-head h3 { font-size: 16px; }
.group-head .count { font-size: 12px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.group-head:first-child { margin-top: 0; }

/* ---- Definition lists ---------------------------------------------------- */

.deflist { display: grid; grid-template-columns: 128px 1fr; gap: 7px 16px; font-size: 14px; }
.deflist dt { color: var(--ink-3); font-size: 12px; padding-top: 2px; }
.deflist dd { margin: 0; overflow-wrap: anywhere; }
.deflist dd.blank { color: var(--rule-2); }
/* Part numbers and serials are read aloud and typed into a search box, so
   they get a face where 0 and O are not the same shape. */
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 13px; }

.prose { white-space: pre-wrap; font-size: 14px; line-height: 1.55; color: var(--ink-2); }

/* ---- Runbook steps -------------------------------------------------------
   Checkable, because the way a runbook is actually used is one-handed, in bad
   light, losing your place. The ticks are not saved anywhere — they last as
   long as the page does, which is exactly as long as the job. */

.steps { list-style: none; margin: 0; padding: 0; counter-reset: step; }
/* The same list, in a task's "How to do it" — see stepsHtml(). It is the same
   markup on purpose: one set of rules, so the two can't drift apart. */
.steps li { cursor: pointer; }
.steps li {
  display: flex; gap: 12px; padding: 13px 0; border-bottom: 1px solid var(--rule);
}
.steps li:last-child { border-bottom: 0; }
.steps .tick {
  flex: 0 0 auto; width: 26px; height: 26px; border: 1px solid var(--rule-2);
  border-radius: 50%; background: var(--paper-2); cursor: pointer;
  display: grid; place-items: center; font-size: 13px; color: var(--ink-3);
  font-variant-numeric: tabular-nums; counter-increment: step;
}
.steps .tick::before { content: counter(step); }
.steps li.done .tick { background: var(--accent); border-color: var(--accent); color: #fff; }
.steps li.done .tick::before { content: '✓'; }
.steps li.done .step-body { color: var(--ink-3); text-decoration: line-through; }
.steps .step-body { font-size: 15px; line-height: 1.5; white-space: pre-wrap; }
.steps .step-outcome {
  font-size: 13px; color: var(--ink-3); margin-top: 3px;
  border-left: 2px solid var(--rule); padding-left: 8px; white-space: pre-wrap;
}
.steps .step-edit { margin-left: auto; }

/* ---- History timeline ---------------------------------------------------- */

.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li { position: relative; padding: 0 0 14px 20px; }
.timeline li::before {
  content: ''; position: absolute; left: 3px; top: 6px; width: 7px; height: 7px;
  border-radius: 50%; background: var(--rule-2);
}
/* The connecting rule, drawn from each dot to the next. Not on the last item. */
.timeline li:not(:last-child)::after {
  content: ''; position: absolute; left: 6px; top: 15px; bottom: 0; width: 1px; background: var(--rule);
}
.timeline .what { font-size: 14px; }
.timeline .when { font-size: 12px; color: var(--ink-3); }
.timeline .unplanned .what::after {
  content: 'unplanned'; font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3); background: var(--paper-3); padding: 1px 5px; border-radius: 3px; margin-left: 7px;
}

/* ---- Empty + loading states ---------------------------------------------- */

.empty {
  text-align: center; padding: 54px 20px; color: var(--ink-3);
  border: 1px dashed var(--rule-2); border-radius: var(--radius);
}
.empty h3 { font-size: 18px; color: var(--ink-2); margin-bottom: 6px; }
.empty p { margin: 0 auto 16px; font-size: 14px; max-width: 40ch; }

.loading { color: var(--ink-3); font-size: 14px; padding: 32px 0; }

/* ---- Drawer -------------------------------------------------------------- */

.drawer-scrim {
  position: fixed; inset: 0; background: rgba(28,26,23,.32); z-index: 40;
  animation: fade .14s ease;
}
@keyframes fade { from { opacity: 0 } to { opacity: 1 } }

.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(820px, 100vw);
  background: var(--paper-2); border-left: 1px solid var(--rule);
  box-shadow: var(--shadow-lg); z-index: 41; display: flex; flex-direction: column;
  animation: slide .16s ease;
}
@keyframes slide { from { transform: translateX(14px); opacity: .6 } to { transform: none; opacity: 1 } }

.drawer-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 18px 24px; border-bottom: 1px solid var(--rule);
}
.drawer-head h2 { font-size: 20px; }
.drawer-body { padding: 24px; overflow-y: auto; flex: 1; }
.drawer-foot {
  display: flex; gap: 8px; align-items: center; padding-top: 18px;
  margin-top: 20px; border-top: 1px solid var(--rule);
}
.drawer-foot .spacer { flex: 1; }

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

.toast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%);
  background: var(--ink); color: var(--paper); font-size: 14px;
  padding: 10px 18px; border-radius: var(--radius); box-shadow: var(--shadow-lg);
  z-index: 60; max-width: min(90vw, 460px);
}
.toast.err { background: var(--danger); }

/* ---- Small screens -------------------------------------------------------
   The pump house is the main use case, not the desk. */

@media (max-width: 900px) {
  /* minmax(0, …) rather than 1fr: see the note on .sidebar. */
  .app { grid-template-columns: minmax(0, 1fr); }
  .sidebar {
    position: static; height: auto; border-right: 0;
    border-bottom: 1px solid var(--rule); padding: 16px 0 0;
  }
  .brand { padding: 0 16px 12px; }
  .nav {
    flex-direction: row; overflow-x: auto; padding: 0 12px 10px; gap: 4px;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
  }
  .nav::-webkit-scrollbar { display: none; }
  .nav-item { white-space: nowrap; }
  .sidebar-foot {
    flex-direction: row; justify-content: space-between; align-items: center;
    padding: 10px 16px; border-top: 1px solid var(--rule); margin-top: 0;
  }
  .main { padding: 22px 16px 64px; }
  .field-row, .field-row-3 { grid-template-columns: 1fr; }
  .drawer { width: 100vw; border-left: 0; }
  .deflist { grid-template-columns: 104px 1fr; }
  .sys-grid { grid-template-columns: 1fr; }
  .row { flex-wrap: wrap; }
  .row .right { text-align: left; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
