/* =========================================================================
   EW ACCOUNTS — shared SPA core

   Loaded by BOTH shells (admin/ and account/) from /core/css/core.css.
   Shell-specific rules live in admin/css/admin.css and
   account/css/account.css — nothing in this file may assume either shell.

   THIS FILE HOLDS NO COLOUR VALUES. Every surface, line, text and accent
   colour comes from a --token defined in a palette file, which each shell
   links BEFORE this one:

     admin/   -> /core/css/tokens-admin.css     dark NOC operator console
     account/ -> /core/css/tokens-account.css   light, roomier, same family

   Both palettes define the same token names, so every component rule below
   works unchanged in either. A literal colour in this file is a bug.
   See .agent/docs/aesthetic.md before changing a token or adding one.
   ========================================================================= */


/* =========================================================================
   Reset & globals
   ========================================================================= */
*, *::before, *::after { box-sizing: border-box; }

/* The hidden attribute always wins. Any rule that sets display (a grid, a
   flex row) otherwise beats the browser's own [hidden] rule, and the element
   stays on screen: the vacation dates showed with "only between these dates"
   unticked, and the nav needed its own override. The one !important here —
   the attribute means "not displayed", so nothing should outrank it. */
[hidden] { display: none !important; }

html, body { margin: 0; padding: 0; height: 100%; }

body {
  background: var(--bg-0);
  color: var(--fg);
  font-family: var(--f-sans);
  font-size: var(--f-size-base);
  line-height: var(--lh-base);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  background-image: var(--bg-texture);
  background-attachment: fixed;
}

h1, h2, h3, h4 { margin: 0; font-weight: 700; letter-spacing: -0.015em; }
h1 { font-size: 22px; }
h3 { font-size: 14px; letter-spacing: 0.02em; }

a { color: var(--amber); text-decoration: none; }
a:hover { color: var(--amber-bright); }

button { font-family: inherit; cursor: pointer; }

code, pre, .mono { font-family: var(--f-mono); }

input, select, textarea, button { font-family: inherit; }

::selection { background: var(--amber-soft); color: var(--fg); }

/* =========================================================================
   App grid
   ========================================================================= */
#app {
  height: 100vh;
  height: 100dvh;              /* a phone's browser bar: 100vh is the screen without it, so the page's foot hid under it */
  overflow: hidden;            /* lock the shell to the viewport; #main scrolls, not the page */
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  grid-template-rows: var(--toolbar-h) 1fr;
  grid-template-areas:
    "brand toolbar"
    "side  main";
}

#toolbar {
  grid-area: toolbar;
  background: var(--bg-1);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  z-index: 50;
}
.toolbar-brand {
  grid-area: brand;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 18px;
  background: var(--bg-0);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.brand-mark {
  width: 8px; height: 18px; background: var(--amber);
  box-shadow: 0 0 0 2px var(--amber-glow);
  flex-shrink: 0;
}
.brand-name {
  font-family: var(--f-mono);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.18em;
  color: var(--fg);
}
.toolbar-end { display: flex; align-items: center; gap: 12px; height: 100%; }

#sidebar {
  grid-area: side;
  background: var(--bg-0);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow-y: auto;
}
.sidebar-nav { padding: 14px 10px; display: flex; flex-direction: column; gap: 1px; }
.nav-section {
  font-family: var(--f-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--amber);
  padding: 18px 10px 6px;
  opacity: 0.85;
}
.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  color: var(--fg-mute);
  font-size: 13.5px;
  font-weight: 500;
  border-radius: var(--r-sm);
  transition: color var(--t-fast), background var(--t-fast);
  position: relative;
}
.nav-item:hover { background: var(--bg-1); color: var(--fg); }
.nav-item.active { background: var(--bg-2); color: var(--fg); }
.nav-item.active::before {
  content: '';
  position: absolute;
  left: -10px; top: 6px; bottom: 6px;
  width: 2px;
  background: var(--amber);
}
.nav-dot {
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--fg-faint);
  flex-shrink: 0;
}
.nav-item:hover .nav-dot, .nav-item.active .nav-dot { background: var(--amber); }

/* -------------------------------------------------------------------------
   Areas — each module's menu, and System (core/js/shell.js). The toolbar
   lists them as tabs; the sidebar shows only the one you are in.
   ------------------------------------------------------------------------- */
.nav-area { display: flex; flex-direction: column; gap: 1px; }
.nav-area:not(.is-current) { display: none; }
.nav-subsection {
  font-family: var(--f-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--fg-dim);
  padding: 12px 10px 4px;
}
.area-bar {
  display: flex;
  align-self: stretch;
  margin: 0 auto 0 -8px;
  overflow-x: auto;
  scrollbar-width: none;
}
.area-tab {
  display: flex;
  align-items: center;
  padding: 0 16px;
  white-space: nowrap;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-mute);
  border-bottom: 2px solid transparent;
  transition: color var(--t-fast), border-color var(--t-fast);
}
.area-tab:hover { color: var(--fg); }
.area-tab.is-current { color: var(--fg); border-bottom-color: var(--amber); }

.sidebar-foot {
  margin-top: auto;
  padding: 12px 14px;
  border-top: 1px solid var(--line);
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 4px 10px;
  font-family: var(--f-mono);
  font-size: 11px;
  color: var(--fg-dim);
}
.sf-key { text-transform: uppercase; letter-spacing: 0.08em; }
.sf-val { color: var(--fg-mute); }
.sf-ok { color: var(--ok); }
.sf-ok::before { content: '● '; }

#main {
  grid-area: main;
  min-width: 0;
  min-height: 0;               /* allow the grid row to stay viewport-height so #main scrolls internally */
  overflow-y: auto;
  background:
    linear-gradient(180deg, var(--bg-1) 0, transparent 240px),
    var(--bg-0);
}
#page-content { padding: 28px 32px 64px; max-width: 1480px; }

/* =========================================================================
   User menu
   ========================================================================= */
.user-menu { position: relative; display: flex; align-items: center; }
.user-menu-trigger {
  display: flex; align-items: center; gap: 8px;
  background: transparent;
  color: var(--fg);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  padding: 6px 10px;
  font-size: 13px;
  font-weight: 500;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.user-menu-trigger:hover { background: var(--bg-2); border-color: var(--line); }
.user-initials { display: none; }       /* in place of the name on a phone (below) */
.user-menu-dropdown {
  position: absolute; top: calc(100% - 4px); right: 0;
  background: var(--bg-2);
  border: 1px solid var(--line-bold);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-md);
  min-width: 160px;
  padding: 4px;
  display: none;
}
.user-menu.open .user-menu-dropdown { display: block; }
.user-menu-dropdown a {
  display: block;
  padding: 8px 12px;
  font-size: 13px;
  color: var(--fg);
  border-radius: var(--r-xs);
}
.user-menu-dropdown a:hover { background: var(--bg-hover); color: var(--amber-bright); }

/* =========================================================================
   Buttons
   ========================================================================= */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 14px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.01em;
  border: 1px solid var(--line-bold);
  border-radius: var(--r-sm);
  background: var(--bg-2);
  color: var(--fg);
  transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.btn:hover { background: var(--bg-3); border-color: var(--line-hover); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }

.btn-primary {
  background: var(--amber);
  color: var(--ink-on-amber);
  border-color: var(--amber);
}
.btn-primary:hover { background: var(--amber-bright); border-color: var(--amber-bright); color: var(--ink-on-amber); }

.btn-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--fg-mute);
}
.btn-ghost:hover { background: var(--bg-2); border-color: var(--line); color: var(--fg); }

.btn-secondary {
  background: var(--bg-2);
  border-color: var(--line-bold);
  color: var(--fg);
}

.btn-danger {
  background: var(--err);
  color: var(--ink-on-err);
  border-color: var(--err);
}
.btn-danger:hover { background: var(--err-bright); border-color: var(--err-bright); }

.btn-danger-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--err);
}
.btn-danger-ghost:hover { background: var(--err-soft); color: var(--err); border-color: var(--err-line); }

.btn-sm { padding: 4px 10px; font-size: 12px; }

/* A button that reads as a link: a table's name cell that opens a drawer
   rather than a route. */
.link-button {
  padding: 0;
  background: none;
  border: none;
  color: var(--amber);
  font: inherit;
  text-align: left;
}
.link-button:hover { color: var(--amber-bright); }

/* =========================================================================
   Page chrome
   ========================================================================= */
.page-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 22px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--line);
}
.page-header h1 {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.02em;
}
.page-header h1::first-letter { color: var(--amber); }
.page-header-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

.page-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}

input[type="search"], input[type="text"], input[type="email"],
input[type="password"], input[type="number"], input[type="date"],
input[type="time"], input[type="datetime-local"], input[type="tel"],
input[type="url"], select, textarea {
  background: var(--bg-1);
  color: var(--fg);
  border: 1px solid var(--line-bold);
  border-radius: var(--r-sm);
  padding: 7px 10px;
  font-size: 13px;
  outline: none;
  transition: border-color var(--t-fast), background var(--t-fast);
  font-family: inherit;
}
input[type="search"] { min-width: 260px; }
input:focus, select:focus, textarea:focus {
  border-color: var(--amber);
  background: var(--bg-2);
  box-shadow: 0 0 0 2px var(--amber-soft);
}
input::placeholder, textarea::placeholder { color: var(--fg-dim); }

/* =========================================================================
   Tabs
   ========================================================================= */
.tab-group {
  display: inline-flex;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 2px;
}
.tab {
  background: transparent;
  border: none;
  color: var(--fg-mute);
  font-size: 12px;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: var(--r-xs);
  letter-spacing: 0.02em;
  transition: color var(--t-fast), background var(--t-fast);
}
.tab:hover { color: var(--fg); }
.tab[aria-pressed="true"] {
  background: var(--bg-3);
  color: var(--amber);
}

.filter-select {
  background: var(--bg-1);
  color: var(--fg);
  border: 1px solid var(--line-bold);
  border-radius: var(--r-sm);
  padding: 6px 10px;
  font-size: 12px;
}

/* =========================================================================
   Cards
   ========================================================================= */
.card {
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  margin-bottom: 18px;
  overflow: hidden;
}
.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-2);
}
.card-header h3 {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fg);
}
.card-body { padding: 16px 18px; }
/* The card's padding is its paragraphs' outer margin. */
.card-body > p:first-child { margin-top: 0; }
.card-body > p:last-child { margin-bottom: 0; }
/* A block inside a card body that sits below the one before it: a revealed
   field group, an alert, the card's save button. */
.card-block { margin-top: 16px; }
/* A heading inside a card (Cleanup's group names) sits clear of what it heads. */
.card-body h3 { margin: 0 0 10px; }

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin-bottom: 24px;
}
.stat-card {
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 16px 18px 18px;
  position: relative;
  overflow: hidden;
}
.stat-card::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: var(--line-bold);
}
.stat-card.warn { border-color: var(--warn-line); }
.stat-card.warn::before { background: var(--amber); }
.stat-label {
  font-family: var(--f-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--fg-mute);
}
.stat-value {
  font-family: var(--f-mono);
  font-size: 32px;
  font-weight: 600;
  font-feature-settings: 'tnum', 'zero';
  color: var(--fg);
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 8px 0 2px;
}
.stat-card.warn .stat-value { color: var(--amber); }
.stat-sub { font-size: 12px; color: var(--fg-mute); }

/* =========================================================================
   Tables
   ========================================================================= */
.table-wrapper { overflow-x: auto; }
table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
thead th {
  text-align: left;
  font-family: var(--f-mono);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--fg-dim);
  padding: 10px 14px;
  background: var(--bg-2);
  border-bottom: 1px solid var(--line-bold);
}
thead th.th-sort {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
thead th.th-sort:hover { color: var(--fg-mute); }
thead th.th-sort:focus-visible {
  outline: 1px solid var(--amber-line);
  outline-offset: -1px;
}
thead th.th-sort-active { color: var(--amber); }
.sort-caret {
  display: inline-block;
  width: 0.9em;
  margin-left: 2px;
  color: var(--amber);
}
tbody td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
  font-variant-numeric: tabular-nums;
}
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover td { background: var(--bg-hover); }
/* A row that opens something on click. Its name cell also carries a real
   link or button, so the keyboard can reach it. */
tbody tr.row-open { cursor: pointer; }

td.text-right, th.text-right { text-align: right; }

/* Column roles (2026-10-01; Eric: "the dates are squished"). Without them the
   browser shares a table's width by each column's longest cell, so one long
   free-text column squeezes every short one onto several lines. Every module
   marks its columns the same way:
     .nowrap      a short value that stays on one line — dates, logins, actions,
                  addresses, badges
     .cell-fill   the one free-text column: takes the width the others leave,
                  and wraps anywhere (long words, JSON) rather than widening
     .cell-clip   …or keeps to one line, cut with an ellipsis; the full text
                  is the row's drawer (or a title) — never only in the clip
   The rule that makes them work: in a table with a .cell-fill or .cell-clip
   column, EVERY other column is .nowrap. That column takes all the slack, so
   any column still allowed to wrap is squeezed to its narrowest (measured:
   the audit log's target went to 43 px and 15 lines). On a narrow window
   the fill/clip column gives way first; past that the table scrolls sideways.
   A list page that wants the whole window puts .page-wide on its root:
   #page-content's 1480 px cap is for reading pages, not wide tables. */
th.nowrap, td.nowrap { white-space: nowrap; }
/* A floor under the fill/clip column (2026-10-03; Eric: "a one character wide
   column with the words running vertically"): with every other column nowrap,
   a table wider than its card squeezed the fill column to nothing — 38 px,
   "ON DISK" one letter a line. Below this width the table scrolls sideways
   in its .table-wrapper instead. */
th.cell-fill, td.cell-fill { width: 100%; min-width: 12rem; overflow-wrap: anywhere; }
td.cell-clip { width: 100%; min-width: 8rem; max-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#page-content:has(.page-wide) { max-width: none; }
td code, td .mono, td.mono, td strong {
  font-family: var(--f-mono);
  font-size: 12.5px;
}
td code {
  background: var(--bg-2);
  padding: 1px 6px;
  border-radius: var(--r-xs);
  color: var(--amber-bright);
}
td strong { color: var(--fg); font-weight: 600; }

/* =========================================================================
   Badges
   ========================================================================= */
.badge {
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
  gap: 5px;
  padding: 2px 8px;
  font-family: var(--f-mono);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  border-radius: var(--r-xs);
  border: 1px solid currentColor;
  background: transparent;
}
.badge::before {
  content: '';
  width: 4px; height: 4px;
  background: currentColor;
  border-radius: 50%;
  flex-shrink: 0;
}
.badge-published, .badge-active { color: var(--ok);    background: var(--ok-soft);    border-color: var(--ok-line); }
.badge-info                      { color: var(--info);  background: var(--info-soft);  border-color: var(--info-line); }
.badge-warning                   { color: var(--warn);  background: var(--warn-soft);  border-color: var(--amber-line); }
.badge-danger                    { color: var(--err);   background: var(--err-soft);   border-color: var(--err-line); }
.badge-critical                  { color: var(--err);   background: var(--err-soft);   border-color: var(--err); }
.badge-draft                     { color: var(--fg-mute); background: var(--bg-2);     border-color: var(--line-bold); }

/* =========================================================================
   Detail grid
   ========================================================================= */
.detail-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));   /* two balanced cards; minmax(0) lets long keys/configs wrap */
  gap: 16px 24px;
  margin: 0 0 18px;
}
@media (max-width: 760px) {
  .detail-grid { grid-template-columns: 1fr; }
}

/* =========================================================================
   Modals
   ========================================================================= */
.modal-overlay {
  position: fixed; inset: 0;
  background: var(--scrim);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 3000;
}
.modal-overlay.hidden { display: none; }
.modal-container {
  background: var(--bg-1);
  border: 1px solid var(--line-bold);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  width: 100%;
  max-width: 520px;
  max-height: calc(100vh - 48px);
  max-height: calc(100dvh - 48px);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  animation: modalIn 200ms cubic-bezier(.16,.84,.44,1);
}
.modal-lg { max-width: 720px; }
.modal-xl { max-width: 980px; }
.modal-scrollable .modal-body { overflow-y: auto; flex: 1 1 auto; }

@keyframes modalIn {
  from { opacity: 0; transform: translateY(8px) scale(0.99); }
  to   { opacity: 1; transform: translateY(0)   scale(1); }
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 22px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-2);
  font-family: var(--f-mono);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--amber);
}
/* close (×) blends into the header and sits on the right — mirrors .inspector-close */
.modal-close {
  background: none; border: none; cursor: pointer;
  color: var(--fg-mute); font-size: 22px; line-height: 1; letter-spacing: 0; padding: 0 2px;
}
.modal-close:hover { color: var(--fg); }
.modal-body { padding: 20px 22px; }
.modal-footer, .modal-actions {
  padding: 14px 22px;
  border-top: 1px solid var(--line);
  background: var(--bg-2);
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

.modal-card { padding: 22px 24px; overflow-y: auto; min-height: 0; }
.modal-card h3 {
  font-family: var(--f-mono);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--amber);
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
}
.modal-card .modal-actions {
  margin: 18px -24px -22px;
}

.modal-confirm-message { font-size: 14px; margin: 0 0 8px; }
.modal-confirm-details {
  font-family: var(--f-mono);
  font-size: 12px;
  color: var(--fg-mute);
  background: var(--bg-2);
  border: 1px solid var(--line);
  padding: 10px 12px;
  border-radius: var(--r-sm);
  margin-top: 10px;
}

/* =========================================================================
   Inspector (right-side overlay drawer) — single reveal surface for
   edit / view-config / connection panels.
   ========================================================================= */
.inspector-scrim {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; justify-content: flex-end;
  background: var(--scrim);
  opacity: 0; transition: opacity var(--t-med);
}
.inspector-scrim.hidden { display: none; }
.inspector-scrim.open { opacity: 1; }
.inspector {
  height: 100%; max-width: 94vw;
  display: flex; flex-direction: column;
  background: var(--bg-1);
  border-left: 1px solid var(--line-bold);
  box-shadow: var(--shadow-panel);
  transform: translateX(100%);
  transition: transform var(--t-med);
}
.inspector-scrim.open .inspector { transform: translateX(0); }
.inspector-header {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 15px 20px; border-bottom: 1px solid var(--line);
}
.inspector-title {
  font-family: var(--f-mono); font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.16em; color: var(--amber);
}
.inspector-close {
  background: none; border: none; cursor: pointer;
  color: var(--fg-mute); font-size: 22px; line-height: 1; padding: 0 2px;
}
.inspector-close:hover { color: var(--fg); }
.inspector-body { flex: 1 1 auto; overflow-y: auto; padding: 18px 20px; min-height: 0; }
.inspector-body h3 { margin: 16px 0 8px; }
.inspector-footer {
  flex: 0 0 auto;
  display: flex; gap: 8px; align-items: center; justify-content: flex-end;
  padding: 13px 20px; border-top: 1px solid var(--line); background: var(--bg-1);
}
@media (prefers-reduced-motion: reduce) {
  .inspector-scrim, .inspector { transition: none; }
}
.inspector-body .config-pre {
  /* Breaks at spaces like prose; mid-word only for a token too long for the line. */
  white-space: pre-wrap; overflow-wrap: anywhere; margin: 0;
  font-size: 12px; line-height: 1.55; color: var(--fg);
}

/* breadcrumb + contextual destructive control on the detail header/properties */
.crumbs { color: var(--fg-mute); font-size: 12px; margin-bottom: 5px; }
.crumbs a { color: var(--fg-mute); }
.crumbs a:hover { color: var(--amber); }
.crumbs span { opacity: .45; margin: 0 3px; }
.btn.key-rotate:hover { color: var(--err); border-color: var(--err-line); }

/* pre-deploy config diff */
.diff {
  font-family: var(--f-mono); font-size: 12px; line-height: 1.5;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  max-height: 60vh; overflow: auto; margin: 0;
}
.diff .l { display: block; white-space: pre-wrap; word-break: break-all; padding: 0 8px; }
.diff .add { color: var(--ok);  background: var(--ok-soft); }
.diff .del { color: var(--err); background: var(--err-soft); }
.diff .ctx { color: var(--fg-mute); }

/* =========================================================================
   Form fields
   ========================================================================= */
.form-field {
  display: block;
  margin: 0 0 14px;
}
.form-field > span,
.form-label {
  display: block;
  font-family: var(--label-font);
  font-size: var(--label-size);
  font-weight: var(--label-weight);
  text-transform: var(--label-case);
  letter-spacing: var(--label-tracking);
  color: var(--fg-mute);
  margin-bottom: 6px;
}
.form-field input,
.form-field select,
.form-field textarea,
.form-input {
  width: 100%;
  background: var(--bg-0);
  border: 1px solid var(--line-bold);
  border-radius: var(--r-sm);
  color: var(--fg);
  padding: 8px 10px;
  font-size: 13px;
  font-family: inherit;
}
.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus,
.form-input:focus {
  border-color: var(--amber);
  background: var(--bg-1);
  box-shadow: 0 0 0 2px var(--amber-soft);
  outline: none;
}
.form-field textarea, textarea.form-input {
  min-height: 80px;
  font-family: var(--textarea-font);
  font-size: var(--textarea-size);
  resize: vertical;
}
/* Data in a field (an address, a uid) opts into mono; the rule above sets
   font-family: inherit, which would otherwise win over plain .mono. */
.form-field input.mono, .form-field textarea.mono, .form-input.mono { font-family: var(--f-mono); }
.form-group { margin-bottom: 14px; }
/* A line of help under a field, pulled up against it. */
.field-hint {
  margin: -4px 0 12px;
  color: var(--fg-mute);
  font-size: 12.5px;
}

/* A short list inside a drawer or card: what an action will do, step by step. */
.plain-list { margin: 0 0 12px 18px; padding: 0; }
.plain-list li { margin: 4px 0; }
/* A rule between two actions in one card (the danger zone: disable, then delete). */
.card-body hr { border: 0; border-top: 1px solid var(--line); margin: 16px 0; }

/* Small buttons that act on the field above (Generate / Copy), pulled up against it. */
.btn-row { display: flex; gap: 8px; margin: -4px 0 12px; }

/* <ew-password-meter>: four segments under a new-password field, filled and
   coloured by level (0 refused … 4 strong), with a word and a hint. */
ew-password-meter { display: block; margin: -4px 0 16px; }
.pw-meter-bar {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
}
.pw-meter-bar span { height: 4px; background: var(--bg-3); border-radius: var(--r-xs); }
.pw-meter-bar[data-level="1"] span:nth-child(-n+1) { background: var(--err); }
.pw-meter-bar[data-level="2"] span:nth-child(-n+2) { background: var(--warn); }
.pw-meter-bar[data-level="3"] span:nth-child(-n+3) { background: var(--info); }
.pw-meter-bar[data-level="4"] span { background: var(--ok); }
.pw-meter-text { min-height: 20px; margin-top: 8px; color: var(--fg-mute); font-size: 12.5px; }
.pw-meter-text strong { color: var(--fg); font-weight: 600; }
.pw-meter-bar[data-level="0"] + .pw-meter-text strong { color: var(--err); }
.pw-meter-note { margin-top: 4px; color: var(--fg-dim); font-size: 12px; }

/* <ew-choice>: one choice out of a few, each with a line of
   explanation, in the space of one field. Closed it is a field (as
   .form-field's inputs are); open, its answers drop below it, over the form. */
ew-choice { display: block; position: relative; margin: 0 0 14px; }
.choice-field {
  width: 100%; min-height: 36px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 8px 10px; text-align: left; cursor: pointer;
  background: var(--bg-0); color: var(--fg);
  border: 1px solid var(--line-bold); border-radius: var(--r-sm);
  font: inherit; font-size: 13.5px;
}
.choice-field:focus-visible { outline: none; border-color: var(--amber); box-shadow: 0 0 0 2px var(--amber-soft); }
.choice-field[aria-expanded="true"] { border-color: var(--amber); }
.choice-shown { min-width: 0; }
.choice-hint { display: block; margin-top: 2px; color: var(--fg-mute); font-size: 12.5px; font-weight: 400; }
.choice-caret { flex: none; color: var(--fg-mute); }
.choice-panel {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 5;
  display: flex; flex-direction: column; gap: 2px; padding: 4px;
  background: var(--bg-2);
  border: 1px solid var(--line-bold); border-radius: var(--r-sm);
  box-shadow: var(--shadow-md);
}
.choice-option {
  display: block; width: 100%; padding: 8px 10px; text-align: left; cursor: pointer;
  background: none; color: var(--fg);
  border: none; border-left: 2px solid transparent; border-radius: var(--r-xs);
  font: inherit; font-size: 13.5px;
}
.choice-option:hover, .choice-option:focus-visible { outline: none; background: var(--bg-hover); }
.choice-option[aria-selected="true"] { border-left-color: var(--amber); }

/* Two-column form layout for roomy modals (e.g. client paths/excludes side by
   side in an xl modal). Each .form-field keeps its own 14px row spacing. */
.form-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 18px;
}
@media (max-width: 680px) {
  .form-grid-2 { grid-template-columns: 1fr; }
}

/* Inline "back up to" destination rows (server -> datastore) in the New Client modal. */
.dest-row {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-bottom: 8px;
}
.dest-row select {
  flex: 1;
  background: var(--bg-0);
  border: 1px solid var(--line-bold);
  border-radius: var(--r-sm);
  color: var(--fg);
  padding: 8px 10px;
  font-size: 13px;
}
.dest-row select:focus {
  border-color: var(--amber);
  outline: none;
  box-shadow: 0 0 0 2px var(--amber-soft);
}

/* Scrollable checkbox list (e.g. batch "Assign clients" on the server page). */
.check-list {
  max-height: 320px;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 4px 10px;
}
.check-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 0;
  cursor: pointer;
}
.check-row input { width: auto; flex-shrink: 0; }
.check-row input:disabled + span { color: var(--fg-mute); }
.form-check { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.form-check input[type="checkbox"] { width: 14px; height: 14px; accent-color: var(--amber); }
.form-check-label { font-size: 13px; color: var(--fg); }
input[type="checkbox"] { accent-color: var(--amber); }

/* On/off switch: <label class="switch"><input type="checkbox"><span class="slider"></span></label>.
   Off is an empty grey track with a grey knob; on is the track filled with the
   status green (`--ok`, Eric's pick of three looks, 2026-10-07) and the knob in
   its ink — the two states share no colour.
   A label-based switch also says "Off" / "On" beside the track, which changes
   the moment the switch moves (Linda could not tell which was which,
   2026-10-07). A <span class="switch"> inside a label with its own words (the
   list filters: "Registered now", "Problems only") gets no word. */
.switch {
  position: relative; display: inline-flex; align-items: center; vertical-align: middle;
  width: 38px; height: 22px; cursor: pointer;
}
label.switch { width: auto; padding-right: 32px; }   /* room for the word */
.switch input { position: absolute; opacity: 0; width: 0; height: 0; margin: 0; }
.slider {
  position: relative; flex: none; width: 38px; height: 22px;
  background: var(--bg-3);
  border: 1px solid var(--line-bold);
  border-radius: 999px;
  transition: background var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast);
}
.slider::before {                       /* the knob */
  content: '';
  position: absolute; left: 3px; top: 50%;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--fg-mute);
  transform: translateY(-50%);
  transition: transform var(--t-fast), background var(--t-fast);
}
label.switch .slider::after {           /* the word */
  content: 'Off';
  position: absolute; left: calc(100% + 8px); top: 50%; transform: translateY(-50%);
  font: 600 12px/1 var(--f-sans); letter-spacing: 0.02em; white-space: nowrap;
  color: var(--fg-mute);
  transition: color var(--t-fast);
}
.switch input:checked + .slider {
  background: var(--ok);
  border-color: var(--ok);
}
.switch input:checked + .slider::before {
  background: var(--ink-on-ok);
  transform: translate(16px, -50%);
}
label.switch input:checked + .slider::after { content: 'On'; color: var(--ok); }
.switch input:focus-visible + .slider { border-color: var(--amber); box-shadow: 0 0 0 2px var(--amber-soft); }
.switch input:disabled + .slider { opacity: 0.45; cursor: not-allowed; }
.switch:has(input:disabled) { cursor: not-allowed; }

/* Permission list (Add User / Edit User / LDAP import modals) */
.perm-list {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--bg-0);
  overflow: hidden;
}
.perm-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line-soft);
}
.perm-row:last-child { border-bottom: none; }
.perm-row:hover     { background: var(--bg-1); }
.perm-meta { min-width: 0; }
.perm-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--fg);
  letter-spacing: 0.01em;
}
.perm-desc {
  font-size: 11.5px;
  color: var(--fg-mute);
  margin-top: 2px;
  line-height: 1.4;
}

/* Settings page — section card with form rows + per-section save bar */
.settings-section {
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  margin-bottom: 18px;
  overflow: hidden;
}
.settings-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-2);
}
.settings-section-head h3 {
  font-family: var(--f-mono);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--amber);
}
.settings-section-head .settings-status {
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg-dim);
}
.settings-section-head .settings-status.on  { color: var(--ok); }
.settings-section-head .settings-status.off { color: var(--fg-dim); }
.settings-saved-hint {
  font-style: normal;
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--fg-dim);
}
.settings-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 18px;
  padding: 18px;
}
.settings-grid > .settings-full { grid-column: 1 / -1; }
.settings-foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding: 12px 18px;
  border-top: 1px solid var(--line);
  background: var(--bg-2);
}
.settings-foot .settings-msg {
  margin-right: auto;
  font-family: var(--f-mono);
  font-size: 11px;
  color: var(--fg-mute);
  letter-spacing: 0.04em;
}
.settings-foot .settings-msg.ok   { color: var(--ok); }
.settings-foot .settings-msg.warn { color: var(--amber); }
.settings-foot .settings-msg.err  { color: var(--err); }
.settings-foot .settings-test-hint {
  font-size: 11px;
  font-style: italic;
  color: var(--amber);
}
.settings-note {
  margin: 0 18px 14px;
  padding: 10px 12px;
  font-size: 12px;
  color: var(--fg-mute);
  border-left: 2px solid var(--amber);
  background: var(--bg-2);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
}

/* =========================================================================
   Toast
   ========================================================================= */
#toast-container {
  position: fixed;
  bottom: 24px; right: 24px;
  display: flex; flex-direction: column; gap: 8px;
  z-index: 4000;
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  min-width: 240px;
  max-width: 360px;
  background: var(--bg-2);
  border: 1px solid var(--line-bold);
  border-left: 3px solid var(--info);
  border-radius: var(--r-sm);
  color: var(--fg);
  padding: 10px 14px;
  font-size: 13px;
  box-shadow: var(--shadow-md);
  animation: toastIn 180ms cubic-bezier(.16,.84,.44,1);
  font-family: var(--f-mono);
  font-weight: 500;
  letter-spacing: 0.01em;
}
.toast-success { border-left-color: var(--ok); }
.toast-error   { border-left-color: var(--err); }
.toast-warning { border-left-color: var(--warn); }
.toast-info    { border-left-color: var(--info); }
.toast.removing { opacity: 0; transform: translateX(8px); transition: opacity 180ms, transform 180ms; }

@keyframes toastIn {
  from { opacity: 0; transform: translateX(12px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* =========================================================================
   Misc states
   ========================================================================= */
.loading-center {
  display: flex; align-items: center; justify-content: center;
  padding: 64px 20px;
}
.spinner {
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 2px solid var(--line-bold);
  border-top-color: var(--amber);
  animation: spin 700ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* small inline spinner for in-button busy states */
.spinner-sm {
  display: inline-block; width: 13px; height: 13px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent;
  animation: spin 700ms linear infinite; vertical-align: -2px; margin-right: 6px;
  opacity: .85;
}

.empty-state {
  text-align: center;
  padding: 56px 20px;
  border: 1px dashed var(--line-bold);
  border-radius: var(--r-md);
  background: var(--bg-1);
}
.empty-state h3 {
  font-family: var(--f-mono);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--amber);
  margin-bottom: 8px;
}
.empty-state p { color: var(--fg-mute); margin: 0 0 14px; }

.pagination {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 12px;
  font-family: var(--f-mono);
  font-size: 11px;
  color: var(--fg-dim);
  letter-spacing: 0.06em;
}

pre.log {
  background: var(--bg-0);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 12px 14px;
  font-family: var(--f-mono);
  font-size: 11px;
  white-space: pre-wrap;
  word-break: break-all;
  max-height: 220px;
  overflow: auto;
  color: var(--amber-bright);
}

.alert {
  padding: 10px 14px;
  border-radius: var(--r-sm);
  font-size: 13px;
  border: 1px solid var(--line-bold);
  background: var(--bg-2);
  margin: 0 0 14px;
}
.alert-danger { border-color: var(--err-line); background: var(--err-soft); color: var(--err); }
.alert-warning { border-color: var(--amber-line); background: var(--warn-soft); color: var(--amber); }
.alert-success { border-color: var(--ok-line); background: var(--ok-soft); color: var(--ok); }
.alert-info    { border-color: var(--info-line); background: var(--info-soft); color: var(--info); }

.text-muted     { color: var(--fg-mute); }
.text-sm        { font-size: 12px; }
.text-right     { text-align: right; }
.inline-flex    { display: inline-flex; gap: 6px; align-items: center; }

/* =========================================================================
   Login screen
   ========================================================================= */
#app.login-active {
  display: block;
  background: var(--bg-0);
  min-height: 100vh;
}
#app.login-active #toolbar,
#app.login-active #sidebar,
#app.login-active .toolbar-brand { display: none; }
.login-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  background: var(--login-texture), var(--bg-0);
}
.login-card {
  width: 100%;
  max-width: 380px;
  background: var(--bg-1);
  border: 1px solid var(--line-bold);
  border-radius: var(--r-lg);
  padding: 36px 32px 28px;
  position: relative;
  box-shadow: var(--shadow-lg);
}
.login-card::before {
  content: '';
  position: absolute;
  inset: -1px;
  padding: 1px;
  border-radius: inherit;
  background: linear-gradient(180deg, var(--amber-line), transparent 40%);
  /* The only hex in this file, and deliberately so: a mask reads alpha, not
     colour. #000 means "fully opaque — keep this area". A palette token could
     be translucent and would silently change the mask. Not a colour value; do
     not tokenise. */
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
}
.login-title {
  font-family: var(--f-mono);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.32em;
  text-align: center;
  color: var(--amber);
  margin: 0 0 6px;
}
.login-title::before { content: '█ '; opacity: 0.7; }
.login-sub {
  text-align: center;
  font-size: 12px;
  color: var(--fg-mute);
  margin-bottom: 22px;
}
.login-card .form-field { margin-bottom: 14px; }
.login-card .btn-primary {
  width: 100%; margin-top: 6px;
  padding: 10px;
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.login-card .alert { font-size: 12px; padding: 8px 10px; }
/* Two-step sign-in's code step: back to the username and password. */
.login-card .login-restart { display: block; margin: 12px auto 0; font-size: 12px; }

.login-foot {
  margin-top: 18px;
  text-align: center;
  font-family: var(--f-mono);
  font-size: 10px;
  color: var(--fg-faint);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* =========================================================================
   First-paint loader (before JS resolves the route)
   ========================================================================= */
.app-loading #page-content::after {
  content: '';
  display: block;
  margin: 120px auto;
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 2px solid var(--line-bold);
  border-top-color: var(--amber);
  animation: spin 700ms linear infinite;
}

/* key/value definition list (detail pages) */
.kv { display: grid; grid-template-columns: max-content 1fr; gap: .4rem .9rem; margin: 0; }
.kv dt {
  color: var(--fg-dim);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  align-self: center;
}
.kv dd { margin: 0; color: var(--fg); }

/* compact select for inline table editing (links route/access) */
.form-input-sm {
  padding: 3px 6px;
  min-width: 122px;
  font-size: 12px;
  font-family: var(--f-mono);
  background: var(--bg-2);
  color: var(--fg);
  border: 1px solid var(--line-bold);
  border-radius: var(--r-xs);
}


/* =========================================================================
   Detail headers, radios, toggle rows, chips
   -------------------------------------------------------------------------
   .toggle-row is the capability switch row (4.4) — one per capability.
   .chip / .chip-list is group membership.
   ========================================================================= */

/* A heading between groups of cards on one page (the Mail section of an
   account). Sentence case, not the card headers' caps. */
.section-heading {
  font-size: 15px; font-weight: 700; color: var(--fg);
  margin: 26px 0 12px; letter-spacing: -0.005em;
}

/* detail header: title + status badges, vertically centered */
.detail-title { display: flex; align-items: center; gap: .55rem; flex-wrap: wrap; }
.detail-title h1 { margin: 0; }

.radio-list { display: flex; flex-direction: column; gap: 5px; margin-top: 5px; }
.radio { display: flex; align-items: center; gap: .5rem; font-size: 13.5px; color: var(--fg); cursor: pointer; }
.radio input { accent-color: var(--amber); }

.toggle-group { margin: .5rem 0; }
.toggle-row {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 10px 0; border-bottom: 1px solid var(--line-soft);
}
.toggle-row:last-child { border-bottom: none; }
.toggle-row strong { font-weight: 600; font-size: 13.5px; }
.toggle-row .switch { flex-shrink: 0; }
.toggle-row .toggle-note { display: block; color: var(--fg-mute); font-size: 12px; margin-top: 2px; }

.chip-list { display: flex; flex-wrap: wrap; gap: 6px; }
.chip-list + .form-field { margin-top: 16px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 6px 2px 8px;
  font-family: var(--f-mono); font-size: 12px;
  color: var(--fg); background: var(--bg-2);
  border: 1px solid var(--line-bold); border-radius: var(--r-sm);
}
.chip-x {
  background: none; border: none; cursor: pointer;
  color: var(--fg-mute); font-size: 13px; line-height: 1; padding: 0;
}
.chip-x:hover { color: var(--err); }

/* A name with a note beside it (Cleanup: "root — a local account…"). */
.chip-note { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 8px 0 0; }

/* A bordered, scrolling list of rows: people to tick (Users → Add from the directory), people to open (Capabilities). */
.scroll-list {
  max-height: 320px; overflow-y: auto; margin-bottom: 12px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
}
.scroll-row {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-bottom: 1px solid var(--line-soft); cursor: pointer;
}
.scroll-row:last-child { border-bottom: none; }
.scroll-row:hover { background: var(--bg-hover); }
.scroll-row > span { flex: 1 1 auto; min-width: 0; }
.scroll-row.is-here { cursor: default; color: var(--fg-mute); }

/* <ew-mail-filters>: a person's own Sieve filters, one line each (plan 2.10). */
.filter-list { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.filter { border: 1px solid var(--line); border-radius: var(--r-sm); padding: 10px 12px; background: var(--bg-1); }
.filter-off { opacity: .6; }
.filter-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 4px; }
.filter-line { font-size: 13.5px; line-height: 1.5; }
.filter-line .text-muted { display: inline-block; min-width: 3.2em; }
.filter-raw { margin: 6px 0 0; padding: 8px 10px; background: var(--bg-2); border-radius: var(--r-xs);
              font-size: 12.5px; white-space: pre-wrap; overflow-wrap: anywhere; }
/* …and editing them, once migrated: tools under each filter, a form in place. */
.filter-buttons { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.filter-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px; }
.filter-tools .form-check { margin: 0 6px; font-size: 13px; }
.filter-note { margin: 6px 0 0; }
.filter-editing { border-color: var(--amber-line); background: var(--bg-2); }
.filter-form { margin-top: 10px; }
.filter-form .form-grid-2 { margin-bottom: 4px; }
.filter-sub { font-family: var(--label-font); font-size: var(--label-size); font-weight: var(--label-weight);
              text-transform: var(--label-case); letter-spacing: var(--label-tracking);
              color: var(--fg-mute); margin: 12px 0 6px; }
.filter-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 8px; }
.filter-row select, .filter-row input { flex: 1 1 150px; min-width: 0; }
.filter-row input[data-c="value"], .filter-row input[data-a="target"] { flex-grow: 2; }
.filter-row .btn { flex: 0 0 auto; }
/* <ew-folder-picker>: the folder tree with a search box (the editor's folder
   actions). The element is display: contents, so in an action row its field
   sits between the action and Remove and its panel wraps to a full-width line
   of its own — opening in place, never floating over the form. */
ew-folder-picker { display: contents; }
.fp-field {
  flex: 2 1 240px; min-width: 0; min-height: 36px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 6px 10px; text-align: left; cursor: pointer;
  background: var(--bg-0); color: var(--fg);
  border: 1px solid var(--line-bold); border-radius: var(--r-sm);
  font: inherit; font-size: 13px;
}
.fp-field:hover { border-color: var(--line-hover); }
.fp-field:focus-visible { outline: none; border-color: var(--amber); box-shadow: 0 0 0 2px var(--amber-soft); }
.fp-field[aria-expanded="true"] { border-color: var(--amber); }
.fp-shown { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; min-width: 0; }
.fp-change { flex: none; font-size: 12px; font-weight: 600; color: var(--amber); }
.fp-placeholder { color: var(--fg-dim); }
.fp-path { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 5px; min-width: 0; overflow-wrap: anywhere; }
.fp-sep { color: var(--fg-faint); }
.fp-parent { color: var(--fg-mute); }
.fp-leaf { color: var(--fg); font-weight: 600; }
.fp-note { color: var(--warn); font-size: 11.5px; font-weight: 400; white-space: nowrap; }
mark.fp-hit { background: var(--amber-soft); color: inherit; border-radius: 2px; box-shadow: 0 0 0 1px var(--amber-line); }
.fp-panel {
  flex: 1 1 100%; order: 10; min-width: 0;
  display: flex; flex-direction: column; gap: 8px; padding: 10px;
  background: var(--bg-1); border: 1px solid var(--line-bold); border-radius: var(--r-sm);
}
.fp-panel input[type="search"] { flex: none; width: 100%; min-width: 0; }
.fp-scroll { max-height: 320px; overflow: auto; overscroll-behavior: contain; border-top: 1px solid var(--line-soft); padding-top: 4px; }
.fp-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; font-size: 12px; color: var(--fg-dim); }
.fp-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.fp-new { color: var(--ok); font-size: 11.5px; font-weight: 600; white-space: nowrap; }
.fp-empty { padding: 12px 6px; color: var(--fg-mute); font-size: 13px; }
.fp-tree, .fp-tree ul { list-style: none; margin: 0; padding: 0; }
.fp-row { position: relative; display: flex; align-items: center; gap: 2px; padding-left: calc(var(--depth, 0) * 18px); }
.fp-twist {
  flex: none; width: 24px; height: 28px; border: none; background: none; cursor: pointer;
  color: var(--fg-mute); border-radius: var(--r-xs); font-size: 11px; line-height: 1;
}
.fp-twist:hover { background: var(--bg-hover); color: var(--fg); }
.fp-twist.is-leaf { visibility: hidden; }
.fp-item {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: baseline; gap: 8px;
  padding: 5px 8px; border: none; background: none; cursor: pointer; text-align: left;
  color: var(--fg); font: inherit; font-size: 13.5px; border-radius: var(--r-xs);
}
.fp-item:hover, .fp-item:focus-visible { background: var(--bg-hover); outline: none; }
.fp-item:focus-visible { box-shadow: inset 0 0 0 1px var(--amber-line); }
.fp-item[aria-selected="true"] { background: var(--amber-soft); box-shadow: inset 3px 0 0 var(--amber); font-weight: 600; }
.fp-sub { color: var(--fg-dim); font-size: 11.5px; font-weight: 400; white-space: nowrap; }
.fp-special { color: var(--fg-mute); }
.fp-implied { color: var(--fg-mute); font-style: italic; }
.fp-hide { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;   /* for screen readers only */
           overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
/* On a phone a row's controls wrap onto several lines: a rule under each row
   shows where one condition or action ends. */
@media (max-width: 680px) {
  .filter-row { margin: 0 0 8px; padding-bottom: 8px; border-bottom: 1px solid var(--line); }
}

/* =========================================================================
   On a phone (Eric, 2026-10-08: "meridian doesn't work on mobile" — the
   console's menu and page split the screen in half). 760 px and under.

   The console's sidebar column becomes a row: the top bar keeps the brand's
   mark, the area tabs and the user menu (initials, set by shell.js), and
   under it the area's pages are one row. Both rows scroll sideways, fade at
   an edge with more beyond it, and keep the current tab and page in view
   (shell.js). The page gets the whole width. The account site has its own
   grid (account.css), hence :not(.no-sidebar) on the console's.

   A wide table scrolls sideways in its card (.table-wrapper), one line a
   row; a drawer takes the whole screen.
   ========================================================================= */
@media (max-width: 760px) {
  #app:not(.no-sidebar) {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: var(--toolbar-h) auto minmax(0, 1fr);
    grid-template-areas:
      "brand toolbar"
      "side  side"
      "main  main";
  }
  #app:not(.no-sidebar) .toolbar-brand { padding: 0 4px 0 14px; border-right: none; }
  #app:not(.no-sidebar) .brand-name { display: none; }
  #app:not(.no-sidebar) #toolbar { padding: 0 8px 0 0; gap: 4px; }

  /* A row that scrolls sideways fades out where there is more of it. Only the
     mask's alpha counts, so any opaque token draws it. The end padding is what
     the fade covers once the row is scrolled to its end. */
  .area-bar, #sidebar {
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    mask-image: linear-gradient(to right, transparent, var(--fg) 10px, var(--fg) calc(100% - 28px), transparent);
  }
  .area-bar::-webkit-scrollbar, #sidebar::-webkit-scrollbar { display: none; }
  .area-bar { margin: 0; padding: 0 24px 0 4px; flex: 1 1 auto; min-width: 0; }
  .area-tab { padding: 0 10px; letter-spacing: 0.08em; }

  #sidebar { flex-direction: row; border-right: none; border-bottom: 1px solid var(--line); }
  #sidebar .sidebar-nav { flex: none; flex-direction: row; align-items: center; padding: 6px 28px 6px 8px; }
  #sidebar .nav-area.is-current { flex-direction: row; align-items: center; gap: 2px; }
  #sidebar .nav-section, #sidebar .nav-subsection, #sidebar .nav-dot, .sidebar-foot { display: none; }
  #sidebar .nav-item { white-space: nowrap; padding: 7px 12px; }
  #sidebar .nav-item.active::before { inset: auto 12px -6px; width: auto; height: 2px; }

  /* The user menu: initials in a ring in place of the name (shell.js fills
     them). A plain box, the letters centred by their line height: centred by
     a grid, Safari drew them dark on the dark bar, and only in their real
     colour once the button's own colour changed — the account site's on a
     touch, the console's never (Eric, 2026-10-08). */
  .user-menu-trigger { gap: 4px; padding: 4px; }
  #user-name { display: none; }
  .user-initials {
    display: inline-block;
    width: 30px; height: 30px;
    border: 1px solid currentColor; border-radius: 50%;
    font: 600 11px/28px var(--f-mono); letter-spacing: 0.04em;
    text-align: center;
    color: inherit; -webkit-text-fill-color: currentColor;
  }

  /* The page: narrower gutters; a title above its actions, which share the width. */
  #page-content { padding: 18px 14px 48px; }
  .page-header { flex-direction: column; align-items: stretch; gap: 12px; margin-bottom: 18px; padding-bottom: 14px; }
  .page-header-actions > * { flex: 1 1 auto; }
  .page-header-actions > .btn-ghost { flex: none; }   /* a link to another view of the page, not an action */
  input[type="search"] { min-width: 0; }
  .page-header-actions input[type="search"], .page-toolbar input[type="search"] { flex: 1 1 100%; }
  .page-toolbar { gap: 8px; }
  .page-toolbar select { flex: 1 1 auto; }
  /* Where you are on the first row, the buttons on the next (::before breaks the row). */
  .pagination { flex-wrap: wrap; justify-content: flex-start; row-gap: 5px; }
  .pagination > * { order: 1; }
  .pagination > [data-range] { order: -2; margin-right: auto; }
  .pagination > [data-at] { order: -1; }
  .pagination::before { content: ''; flex-basis: 100%; order: 0; }

  .card-header { padding: 12px 14px; }
  .card-body { padding: 14px; }
  /* Cards one under another; numbers (stat cards) two a row. */
  .card-grid { grid-template-columns: minmax(0, 1fr); gap: 10px; margin-bottom: 18px; }
  .card-grid:has(.stat-card) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stat-card { padding: 12px 14px 14px; }
  .stat-value { font-size: 26px; }

  .tab-group { display: flex; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
  .tab { flex: none; white-space: nowrap; }

  thead th, tbody td { padding: 9px 10px; }
  tbody td:not(.cell-fill) { white-space: nowrap; }

  .inspector { max-width: 100%; }
  .inspector-header, .inspector-footer { padding-left: 16px; padding-right: 16px; }
  .inspector-body { padding: 16px; }
  .modal-overlay { padding: 12px; }
  .modal-container { max-height: calc(100dvh - 24px); }
}

/* iPhone and iPad Safari draw a date or time field as their own control, as
   wide as they like whatever width it is given: it ran past the card's right
   edge (Eric, 2026-10-08, the automatic reply's First and Last day). Without
   the native look the field keeps its width; a tap still opens the date
   wheel. The value inside loses Safari's 24 px right margin and its centring,
   and keeps a line's height when empty (it collapsed without the look).
   `-webkit-touch-callout` is only known to iPhone and iPad Safari, so no
   other browser changes. */
@supports (-webkit-touch-callout: none) {
  input[type="date"], input[type="time"], input[type="datetime-local"] {
    -webkit-appearance: none;
    appearance: none;
    min-width: 0;
  }
  input::-webkit-date-and-time-value { margin: 0; min-height: 1.5em; text-align: left; }
}

/* iPhone and iPad Safari zoom the page in when a field whose text is under
   16px is touched, and leave it zoomed until it is pinched back. So on a touch
   screen every field is 16px (Eric, 2026-10-03: the sign-in on both sites).
   Not `maximum-scale=1` in the viewport: that would also stop anyone zooming
   on purpose. The list repeats each field rule above that sets a size, so
   this one, being later, wins; a new rule giving a field a size belongs here
   too. */
@media (hover: none) and (pointer: coarse) {
  input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"], [type="color"], [type="hidden"]),
  select, textarea,
  .form-field input, .form-field select, .form-field textarea, .form-input,
  textarea.form-input, .filter-select, .dest-row select, .form-input-sm {
    font-size: 16px;
  }
}
