/* ==========================================================================
   PUDL, the Pleasantly Usable Design Language (pronounced "puddle").
   Version 0.10.0.

   PUDL gives every affordance one visual representation, so that somebody
   who has learned it once can use any application built with it on sight.

   Elevation signals interactivity:
     - Raised, with a hairline border and an inset highlight, is pressable (.btn).
     - Sunken, with an inset shadow, is an input (.form-input).
     - Flat is display only (.kv-table cells, .form-input[readonly]).
   Colour is never the only signal: every meaningful state carries a glyph.
   One .btn-primary per visible context.

   A project themes PUDL with a stylesheet loaded after this one. It may
   change any colour token, including the background and the topbar, and
   the font tokens, within the restrictions in the README. It never changes
   what a raised, sunken or flat surface means.

   Extracted from the Andoneer Design Language v2 reference page
   (Andoneer repository, mockups/adl-v2-reference.html, commit 097a9c7).
   ========================================================================== */

/* Inter, by Rasmus Andersson, under the SIL Open Font License 1.1
   (fonts/Inter-LICENSE.txt). One variable file covers weights 400 to 700,
   and its optical-size axis tightens the face at heading sizes. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/InterVariable.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/InterVariable-Italic.woff2") format("woff2");
}

:root {
  /* === The palette ==========================================================
     These are the values a project theme sets. Everything under "Derived"
     further down is computed from them, so a new palette is this block and
     its dark counterpart, and nothing else. Set them on :root and on
     [data-theme="dark"], because the derived tokens are computed there. */

  /* Page and text. */
  --bg: #f3f4f6;
  --surface: #fbfbfc;
  --surface-alt: #e4e7eb;
  --text: #1b1f24;
  --text-muted: #5f6873;
  --border: #cfd4da;

  /* Accent and status. */
  --accent: #2c5282;
  --accent-hover: #1f3d63;
  --on-accent: #ffffff;
  --warn: #b86e1c;
  --danger: #b42318;
  --danger-hover: #8f1c13;
  --pr: #2e7d4f;                  /* positive: shipped, done */

  /* Lighting. --light is the colour of the light falling on a raised control
     and --shade the colour of its shadow. --lit sets how strongly the light
     shows and --depth how strongly the shadow does. A light theme wants a
     strong highlight and a soft shadow; a dark theme wants the reverse. */
  --light: #ffffff;
  --shade: #0e1621;
  --lit: 90%;
  --depth: 18%;

  /* Topbar. It keeps its own colours so that it can stay dark on a light
     page, as the default palette does. */
  --tb-bg: #262b31;
  --tb-fg: #f3f4f6;

  /* Fonts. A theme may change these within the roles the README sets out.
     Inter ships with PUDL in fonts/, so it does not depend on what the
     reader has installed; the system face stands in until it loads. */
  --font: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-display: var(--font);
  --mono: ui-monospace, "Cascadia Code", "SF Mono", Consolas, monospace;

  /* === Fixed by the language ================================================
     A theme does not change the radii. */
  --radius: 12px;        /* cards */
  --radius-sm: 7px;      /* buttons and entries */
  --radius-pill: 999px;

  /* === Derived ==============================================================
     Computed from the palette. A theme should not need to set any of these. */

  /* Inputs are sunken, so they take the surface with only a touch of light. */
  --input-bg: color-mix(in srgb, var(--light) var(--lit), var(--surface));

  /* Raised controls: lit from the top, shading to the recessed tint. */
  --raise-top: color-mix(in srgb, var(--light) var(--lit), var(--surface-alt));
  --raise-grad: linear-gradient(var(--raise-top), var(--surface-alt));
  --raise-grad-hover: linear-gradient(
      color-mix(in srgb, var(--text) 3%, var(--raise-top)),
      color-mix(in srgb, var(--text) 6%, var(--surface-alt)));
  --raise-active-bg: color-mix(in srgb, var(--shade) calc(var(--depth) * 0.45), var(--surface-alt));
  --raise-border: color-mix(in srgb, var(--shade) calc(var(--depth) * 0.9), var(--surface-alt));
  --raise-border-hover: color-mix(in srgb, var(--shade) calc(var(--depth) * 1.6), var(--surface-alt));
  --raise-shadow:
      inset 0 1px color-mix(in srgb, var(--light) var(--lit), transparent),
      0 1px 2px color-mix(in srgb, var(--shade) var(--depth), transparent);
  --raise-active-shadow: inset 0 1px 3px color-mix(in srgb, var(--shade) calc(var(--depth) * 1.2), transparent);
  --entry-shadow: inset 0 1px 2px color-mix(in srgb, var(--shade) calc(var(--depth) * 0.7), transparent);

  --shadow-btn-primary:
      inset 0 1px rgb(255 255 255 / 0.25),
      0 1px 2px color-mix(in srgb, var(--shade) calc(var(--depth) * 1.2), transparent);
  --shadow-card:
      0 1px 3px color-mix(in srgb, var(--shade) calc(var(--depth) * 0.6), transparent),
      0 0 0 1px color-mix(in srgb, var(--shade) calc(var(--depth) * 0.25), transparent);

  /* Both rings derive from their colour tokens, so a theme's accent reaches
     the focus ring with no further work. */
  --focus-ring: color-mix(in srgb, var(--accent) 26%, transparent);
  --focus-ring-danger: color-mix(in srgb, var(--danger) 26%, transparent);

  /* The dialog panel is always one step brighter than the page, so it reads
     as a card lifted off it. On a light page that is --surface. */
  --dialog-bg: var(--surface);

  /* Topbar chrome. */
  --tb-grad: linear-gradient(color-mix(in srgb, var(--tb-fg) 8%, var(--tb-bg)), var(--tb-bg));
  --tb-border: color-mix(in srgb, #000 40%, var(--tb-bg));
  --tb-hi: color-mix(in srgb, var(--tb-fg) 12%, transparent);
  --tb-brand: var(--tb-fg);
  --tb-chrome-fg: color-mix(in srgb, var(--tb-fg) 80%, var(--tb-bg));
  --tb-chrome-hover-fg: var(--tb-fg);
  --tb-chip: linear-gradient(
      color-mix(in srgb, var(--tb-fg) 19%, transparent),
      color-mix(in srgb, var(--tb-fg) 10%, transparent));
  --tb-chip-shadow:
      inset 0 1px color-mix(in srgb, var(--tb-fg) 22%, transparent),
      0 1px 2px color-mix(in srgb, #000 35%, transparent);
}

[data-theme="dark"] {
  /* === The dark palette ==================================================== */
  --bg: #121417;
  --surface: #1a1d21;
  --surface-alt: #23272d;
  --text: #e6e8eb;
  --text-muted: #9aa3ad;
  --border: #353b43;

  --accent: #6b9bd1;
  --accent-hover: #8db3e0;
  --on-accent: #121417;
  --warn: #d9954a;
  --danger: #e06156;
  --danger-hover: #f0857b;
  --pr: #5fb37f;

  --light: #e8eef6;
  --shade: #000000;
  --lit: 7%;
  --depth: 48%;

  --tb-bg: #262b31;
  --tb-fg: #e6e8eb;

  /* On a dark page --surface is barely lighter than --bg, so the dialog
     takes the next step up to keep reading as lifted. */
  --dialog-bg: var(--surface-alt);
}

:root[data-theme="dark"] { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

/* The hidden attribute always hides, even on a component that sets its own
   display, which would otherwise beat the browser's rule. hidden="until-found"
   is left to the browser, which hides it by other means so that in-page
   search can still reveal it. */
[hidden]:not([hidden="until-found"]) { display: none !important; }
body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* Tabular numerals wherever numbers are data, so identifiers, counts, money
   and timestamps line up. Running prose keeps proportional figures, because
   Inter's tabular feature also widens the hyphen, which spaces out every
   hyphenated word. <time>, <data> and .num mark data inside prose. */
table, input, select, textarea, time, data, output, code, kbd, samp, .num,
.kv-table, .form-input, .badge, .chip, .filter-chip, .seg, .topbar-pill,
.md-item, .md-row {
  font-variant-numeric: tabular-nums;
}

/* === Topbar / brand chrome ============================================== */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 20px;
  background: var(--tb-grad);
  border-bottom: 1px solid var(--tb-border);
  box-shadow: inset 0 1px var(--tb-hi);
}
.brand {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-display);
  font-size: 17px; font-weight: 700; letter-spacing: -0.01em;
  color: var(--tb-brand); text-decoration: none;
}
.topbar-chrome {
  display: inline-flex; align-items: center; gap: 8px;
}
/* A topbar pill is raised, so it is always a link or a button, never a label. */
.topbar-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 600;
  color: var(--tb-chrome-fg);
  background: var(--tb-chip); box-shadow: var(--tb-chip-shadow);
  text-decoration: none;
}
.topbar-pill:hover { color: var(--tb-chrome-hover-fg); }
/* The theme toggle shares the chip styling on the topbar chrome. */
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  padding: 0; border-radius: var(--radius-sm);
  font-size: 14px; line-height: 1; font-family: var(--font);
  color: var(--tb-chrome-fg);
  background: var(--tb-chip); box-shadow: var(--tb-chip-shadow);
  border: 0; cursor: pointer;
}
.theme-toggle:hover { color: var(--tb-chrome-hover-fg); }

/* === Sub-nav / notebook tab strip ======================================= */
/* After the notebook widget in desktop toolkits: a recessed band of inactive tabs; the active tab "punches
   through" the baseline so it visually merges with the content below.
   Use it for section navigation within a page. */
.app-section-bar {
  display: flex; padding: 0 16px;
  background: var(--surface-alt);
  border-bottom: 1px solid var(--border);
}
.section-tab {
  padding: 9px 14px 8px;
  font-size: 13px; font-weight: 600;
  color: var(--text-muted); text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.section-tab:hover { color: var(--text); }
.section-tab.active {
  color: var(--text); background: var(--surface);
  border-bottom-color: var(--surface);
  box-shadow: inset 0 1px var(--border), 1px 0 var(--border), -1px 0 var(--border);
}

/* === Buttons (raised; one look) ========================================= */
/* Every button is raised. There is no flat. Disabled is dimmed.
   At most one .btn-primary per visible context. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 7px 14px; border-radius: var(--radius-sm);
  font-size: 14px; font-weight: 600; font-family: var(--font);
  color: var(--text); cursor: pointer; text-decoration: none;
  white-space: nowrap;
  border: 1px solid var(--raise-border);
  background: var(--raise-grad);
  box-shadow: var(--raise-shadow);
  transition: background .1s, border-color .1s, box-shadow .1s;
}
.btn:hover {
  background: var(--raise-grad-hover);
  border-color: var(--raise-border-hover);
  text-decoration: none;
}
.btn:active {
  background: var(--raise-active-bg);
  box-shadow: var(--raise-active-shadow);
}
.btn:focus-visible {
  outline: none;
  box-shadow: var(--raise-shadow), 0 0 0 3px var(--focus-ring);
}
/* A toggle button latched on stays pressed in. aria-pressed carries the
   state to assistive technology as well as to the eye, and the state shows
   through elevation, not colour. A project flips the attribute. */
.btn[aria-pressed="true"],
.btn[aria-pressed="true"]:hover {
  background: var(--raise-active-bg);
  border-color: var(--raise-border-hover);
  box-shadow: var(--raise-active-shadow);
}
.btn[aria-pressed="true"]:focus-visible {
  box-shadow: var(--raise-active-shadow), 0 0 0 3px var(--focus-ring);
}
.btn[disabled], .btn.is-disabled {
  opacity: .45; cursor: not-allowed;
  box-shadow: var(--raise-shadow);
  background: var(--raise-grad);
}
.btn-sm { padding: 4px 10px; font-size: 12.5px; }
.btn-primary {
  color: var(--on-accent);
  border-color: color-mix(in srgb, var(--accent) 62%, #000);
  background: linear-gradient(color-mix(in srgb, var(--accent) 78%, #fff), var(--accent));
  box-shadow: var(--shadow-btn-primary);
}
.btn-primary:hover {
  color: var(--on-accent);
  background: linear-gradient(color-mix(in srgb, var(--accent) 88%, #fff), color-mix(in srgb, var(--accent) 94%, #000));
}
.btn-primary:active {
  background: color-mix(in srgb, var(--accent) 86%, #000);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.32);
}
.btn-danger {
  color: var(--danger); border-color: color-mix(in srgb, var(--danger) 35%, var(--raise-border));
}
.btn-danger:hover {
  color: var(--on-accent);
  background: linear-gradient(color-mix(in srgb, var(--danger) 78%, #fff), var(--danger));
  border-color: color-mix(in srgb, var(--danger) 62%, #000);
}

/* Icon button: raised square for row actions (drag, remove, archive). */
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: var(--radius-sm);
  background: var(--raise-grad); border: 1px solid var(--raise-border);
  box-shadow: var(--raise-shadow);
  color: var(--text-muted); cursor: pointer;
}
.icon-btn:hover { color: var(--text); background: var(--raise-grad-hover); border-color: var(--raise-border-hover); }
.icon-btn.danger:hover { color: var(--danger); }

/* === Links ============================================================== */
a, .link {
  color: var(--accent); text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: 2px;
}
a:hover, .link:hover {
  color: var(--accent-hover);
  text-decoration-thickness: 2px;
}
.link-muted {
  color: var(--text-muted); text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: 2px;
}
.link-muted:hover { color: var(--text); }
button.link {
  border: 0; background: none; padding: 0; font: inherit; cursor: pointer;
  color: var(--accent); text-decoration: underline;
}

/* === Forms ============================================================== */
.form-group { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.form-label { font-size: 13px; font-weight: 600; color: var(--text); }
.form-input, .form-select, .form-textarea {
  padding: 8px 11px; font-size: 14px; font-family: var(--font);
  background: var(--input-bg); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  width: 100%;
  box-shadow: var(--entry-shadow);
}
.form-textarea { min-height: 5em; resize: vertical; line-height: 1.5; }
.form-input:focus, .form-select:focus, .form-textarea:focus {
  border-color: var(--accent); outline: none;
  box-shadow: var(--entry-shadow), 0 0 0 3px var(--focus-ring);
}
/* Read-only fields render as flat display, not input chrome. */
.form-input[readonly], .form-select[disabled] {
  background: transparent; border-color: transparent; box-shadow: none;
  padding-left: 0; padding-right: 0; cursor: default;
}
::placeholder { color: var(--text-muted); opacity: .5; }

/* Checkbox + label as one inline control. */
.check {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 14px; cursor: pointer;
}
.check input { width: 16px; height: 16px; margin: 0; accent-color: var(--accent); }

/* Toggle switch (boolean preference). Submit button styled as a slider. */
.switch {
  display: inline-flex; align-items: center; gap: 10px;
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: var(--text); cursor: pointer;
}
.switch-track {
  position: relative; flex: none;
  width: 40px; height: 22px; border-radius: var(--radius-pill);
  background: var(--surface-alt); border: 1px solid var(--border);
  transition: background .15s, border-color .15s;
}
.switch-thumb {
  position: absolute; top: 2px; left: 2px;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--text-muted);
  transition: transform .15s, background .15s;
}
.switch[aria-checked="true"] .switch-track {
  background: var(--accent); border-color: var(--accent-hover);
}
.switch[aria-checked="true"] .switch-thumb {
  transform: translateX(18px); background: var(--on-accent);
}
.switch:focus-visible .switch-track {
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.form-error {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; color: var(--danger); margin: 4px 0 12px;
}
.form-error::before { content: "⚠"; }

/* === Segmented control / view switcher ================================== */
/* Inset trough with raised active segment. Use for boolean / few-option
   choices (a small scale, kg|lbs, Read|Edit). */
.seg {
  display: inline-flex; padding: 3px; gap: 2px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.08);
}
.seg button {
  padding: 4px 12px; border-radius: 4px;
  background: transparent; border: 0; cursor: pointer;
  font: 600 13px var(--font); color: var(--text-muted);
}
.seg button:hover { color: var(--text); }
.seg button.active {
  color: var(--text);
  background: var(--raise-grad);
  border: 1px solid var(--raise-border);
  box-shadow: var(--raise-shadow);
}
.seg.pill { border-radius: var(--radius-pill); }
.seg.pill button { border-radius: var(--radius-pill); }
.seg.sm button { padding: 2px 9px; font-size: 12px; }

/* === Badges + chips ===================================================== */
/* Badge: a state pill carrying a glyph + label (color + glyph redundancy).
   Use it for the state of an entity: open, overdue, done, and so on. */
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 8px; border-radius: var(--radius-pill);
  font-size: 11.5px; font-weight: 700; line-height: 1.55;
  background: color-mix(in srgb, var(--text-muted) 18%, transparent);
  color: var(--text);
}
.badge.warn { background: color-mix(in srgb, var(--warn) 22%, transparent); color: var(--warn); }
.badge.danger { background: color-mix(in srgb, var(--danger) 18%, transparent); color: var(--danger); }
.badge.pr { background: color-mix(in srgb, var(--pr) 22%, transparent); color: var(--pr); }
.badge.accent { background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--accent); }
.badge::before {
  font-size: 9px; line-height: 1;
}
.badge.warn::before { content: "▲"; }
.badge.danger::before { content: "■"; }
.badge.pr::before { content: "●"; }
.badge.accent::before { content: "◆"; }

/* Chip: a flat, accent-tinted metadata pill for an attribute a thing
   carries, such as a tag or a category. It has no border and no shadow.
   A badge says "this is the state"; a chip says "this has the attribute". */
.chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 8px; border-radius: var(--radius-sm);
  font-size: 11.5px; font-weight: 600;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}

/* === Cards ============================================================== */
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 18px;
  box-shadow: var(--shadow-card);
}
.card-title { margin: 0 0 6px; font-size: 16px; font-weight: 700; }
.card-subtitle { margin: 0 0 6px; font-size: 13px; font-weight: 600; color: var(--text-muted); }
.card-desc { margin: 0 0 14px; font-size: 13px; color: var(--text-muted); }

/* === Key/value table for read-only record fields ======================== */
/* Detail panes use this for displayed-only fields, not fake input boxes
   (elevation = interactivity). */
.kv-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.kv-table th {
  text-align: left; font-weight: 600; color: var(--text-muted); font-size: 13px;
  padding: 8px 16px 8px 0; white-space: nowrap; vertical-align: top; width: 1%;
}
.kv-table td { padding: 8px 0; color: var(--text); vertical-align: top; overflow-wrap: anywhere; }
.kv-table tr + tr th, .kv-table tr + tr td { border-top: 1px solid var(--border); }

/* === Server-rendered dialogs ============================================
   The backdrop dims gently, to 40%, because the panel's shadow does the
   elevation work. Padding is generous and the drop shadow is large so the
   panel reads as lifted. The panel is always one step brighter than the
   page, and in dark mode that brightness step is what separates them. */
.dialog-backdrop {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center; padding: 24px;
  background: color-mix(in srgb, #000 40%, transparent);
}
.dialog-backdrop[hidden] { display: none; }
.dialog {
  width: 100%; max-width: 480px;
  background: var(--dialog-bg, var(--surface));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow:
      var(--shadow-card),
      0 24px 64px rgba(0, 0, 0, 0.32);
  padding: 24px 26px;
}
.dialog-title {
  margin: 0 0 8px;
  font-size: 17px; font-weight: 700;
  color: var(--text);
}
.dialog-body {
  margin: 0 0 22px;
  color: var(--text-muted);
  font-size: 14px; line-height: 1.55;
}
.dialog-actions {
  display: flex; justify-content: flex-end; gap: 8px;
}

/* === Master–detail layout (the new primary layout primitive) ============ */
/* body:has(> .md-layout) is full-viewport flex; the toolbar + chip row +
   body fill the page. Scoped to a DIRECT child so a reference demo or any
   other embedded .md-layout doesn't accidentally kill page scrolling. */
body:has(> .md-layout) {
  height: 100vh; display: flex; flex-direction: column; overflow: hidden;
}
.md-layout {
  display: flex; flex-direction: column; flex: 1; min-height: 0;
}
.md-toolbar {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 16px; background: var(--surface);
  border-bottom: 1px solid var(--border); flex: none;
  --ctl-h: 30px;
}
.md-toolbar .btn-sm,
.md-toolbar .seg,
.md-toolbar .md-filter {
  box-sizing: border-box; height: var(--ctl-h);
  display: inline-flex; align-items: center;
}
.md-toolbar .md-filter { padding: 4px 12px; }
.md-filter {
  box-sizing: border-box; flex: none; width: 220px;
  padding: 6px 11px; font-size: 13px;
  background: var(--input-bg); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  box-shadow: var(--entry-shadow);
}
.md-filter:focus {
  border-color: var(--accent); outline: none;
  box-shadow: var(--entry-shadow), 0 0 0 3px var(--focus-ring);
}
.md-toolbar-spacer { flex: 1; }
.md-toolbar-cmds {
  flex: none; display: flex; align-items: center; gap: 6px;
}
.md-toolbar-sep {
  width: 1px; height: var(--ctl-h);
  background: var(--border); align-self: center; margin: 0 4px;
}

/* Active-filter chips, below the toolbar. */
.md-chips {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 8px 16px; background: var(--surface);
  border-bottom: 1px solid var(--border); flex: none;
}
.md-chips:empty { display: none; }
.filter-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 6px 3px 10px;
  border-radius: var(--radius-pill);
  font-size: 12px; font-weight: 600;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}
.fc-kind {
  opacity: .65; font-weight: 500; font-size: 10px;
  text-transform: uppercase; letter-spacing: .04em;
}
.filter-chip-x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 50%;
  background: none; color: inherit; text-decoration: none;
  font-size: 14px; line-height: 1; opacity: .7;
}
.filter-chip-x:hover {
  opacity: 1; background: color-mix(in srgb, var(--accent) 28%, transparent);
}
.md-chips-clear {
  font-size: 12px; color: var(--accent); text-decoration: underline; cursor: pointer;
}

/* Body row: sidebar + resize + detail. */
.md-body { display: flex; flex: 1; min-height: 0; }
.md-sidebar {
  width: var(--md-sidebar-w, 260px); flex: none; min-height: 0; overflow-y: auto;
  background: var(--surface); border-right: 1px solid var(--border);
}
.md-resize {
  flex: none; width: 6px; margin: 0 -3px; z-index: 3; cursor: col-resize;
  background: transparent; position: relative;
}
.md-resize::before {
  content: ""; position: absolute; inset: 0 2px; border-radius: 2px;
  background: transparent; transition: background .12s;
}
.md-resize:hover::before { background: var(--accent); }
.md-detail {
  flex: 1; overflow-y: auto; padding: 24px; min-width: 0;
  background: var(--bg);
}

/* The back link returns from a record to its list. It shows only when the
   layout is narrow enough to show one pane at a time. */
.md-back { display: none; }

/* === One pane at a time =================================================
   When the layout itself is 640px wide or less (a phone, or a narrow window
   or panel on a larger screen), it shows either the list or the record,
   never both. The server says which with data-md-pane on .md-layout:
   "detail" when the URL names a record, and "list", or nothing, otherwise.
   Each pane is its own URL, so Back, reload and sharing all work, and the
   detail's .md-back link returns to the list. */
.md-layout { container: md / inline-size; }

@container md (max-width: 640px) {
  .md-toolbar { flex-wrap: wrap; padding: 8px 12px; }
  .md-toolbar .md-filter { flex: 1 1 100%; width: auto; }
  .md-toolbar-spacer { display: none; }
  .md-toolbar-cmds { flex-wrap: wrap; }
  .md-resize { display: none; }

  /* The list pane fills the layout, and its rows are touch targets. */
  .md-sidebar { flex: 1; width: auto; border-right: 0; }
  .md-sidebar .md-item { padding-top: 10px; padding-bottom: 10px; }
  .md-detail { display: none; padding: 16px; }

  /* The detail pane: the list, its toolbar and its filters step aside. A
     toolbar of site-wide tools, such as a launcher or a window dock, is
     marked .md-site-tools and stays in both panes. */
  .md-layout[data-md-pane="detail"] .md-toolbar:not(.md-site-tools),
  .md-layout[data-md-pane="detail"] .md-chips,
  .md-layout[data-md-pane="detail"] .md-sidebar { display: none; }
  .md-layout[data-md-pane="detail"] .md-detail { display: block; }

  .md-back {
    display: inline-flex; align-items: center; gap: 4px;
    margin-bottom: 12px;
    font-size: 14px; font-weight: 600;
  }
  .md-back::before { content: "\2039"; font-size: 18px; line-height: 1; text-decoration: none; }
}

/* Sidebar rows: compact text list (not big touch targets); 3px accent edge
   on the side facing the detail pane for the active row. */
.md-section-label {
  padding: 14px 14px 4px;
  font-size: 11px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-muted);
}
.md-row {
  display: flex; align-items: center;
  border-right: 3px solid transparent;
  border-bottom: 1px solid var(--surface-alt);
}
.md-row:hover { background: var(--surface-alt); }
.md-row.active {
  background: var(--surface-alt);
  border-right-color: var(--accent);
}
.md-row.active .md-item { font-weight: 700; color: var(--text); }
.md-item {
  flex: 1; min-width: 0;
  padding: 5px 14px;
  font-size: 13px; line-height: 1.5;
  color: var(--text); text-decoration: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  cursor: pointer;
}
.md-item .md-meta {
  display: block; font-size: 11px; font-weight: 500; color: var(--text-muted);
}
.md-grip {
  flex: none; width: 22px; text-align: center; cursor: grab;
  color: var(--text-muted); font-size: 14px; line-height: 1;
}

/* === Menus ===============================================================
   A menu button opens a panel of choices: places to go, and actions. The
   button is raised and carries a caret, so it reads as opening something
   rather than doing something, and it shows pressed while its panel is
   open. The panel is lifted like a dialog, without a backdrop, because it
   is not modal. It is an HTML popover, so it opens, closes on Escape or an
   outside click, and sits above everything with no script; pudl-menu.js
   places it against its button and adds the arrow keys and filtering.

   Places in a panel are list rows, the .md-row and .md-item of the
   master-detail sidebar, grouped under .md-section-label headings. Actions
   are .menu-action buttons, set apart by an .menu-sep rule. */
.menu { display: inline-flex; position: relative; }
.menu-btn::after {
  content: "\25BE"; font-size: 11px; line-height: 1; opacity: .75;
}
.menu:has(> .menu-panel:popover-open) > .menu-btn {
  background: var(--raise-active-bg);
  box-shadow: var(--raise-active-shadow);
}

.menu-panel {
  margin: auto; padding: 6px 0;
  min-width: 14rem; max-width: min(22rem, calc(100vw - 16px));
  max-height: min(32rem, calc(100vh - 16px));
  overflow: auto;
  background: var(--dialog-bg, var(--surface)); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow:
      var(--shadow-card),
      0 16px 40px color-mix(in srgb, var(--shade) calc(var(--depth) * 1.6), transparent);
  font-family: var(--font);
}
/* The script hides a panel for the moment between opening and placing it,
   so it never flashes in the middle of the screen. */
.menu-panel.placing { visibility: hidden; }
/* On a narrow screen the script opens the panel as a sheet across the full
   width, so its rows stay large enough to tap. */
.menu-panel.sheet {
  width: 100%; max-width: none;
  border-width: 0 0 1px; border-radius: 0 0 var(--radius) var(--radius);
}
.menu-panel.sheet .md-item { padding-top: 10px; padding-bottom: 10px; }

.menu-panel .md-section-label { padding: 10px 14px 4px; }
.menu-panel .md-section-label:first-child { padding-top: 6px; }
.menu-panel .md-row { border-bottom: 0; }
.menu-panel .md-item:focus-visible,
.menu-action:focus-visible {
  outline: none; background: var(--surface-alt);
  box-shadow: inset 3px 0 var(--accent);
}
.menu-panel .md-filter { display: block; width: calc(100% - 20px); margin: 4px 10px 6px; }
.menu-panel form { margin: 0; }
.menu-empty { margin: 0; padding: 6px 14px; font-size: 13px; color: var(--text-muted); }

.menu-sep { border: 0; border-top: 1px solid var(--border); margin: 6px 0; }
.menu-action {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 6px 14px;
  background: none; border: 0; border-radius: 0;
  font: 13px/1.5 var(--font); color: var(--text); text-align: left;
  cursor: pointer;
}
.menu-action:hover { background: var(--surface-alt); }
.menu-action.danger { color: var(--danger); }
