/* P47.6: these two were pulled in here by CSS include and therefore
   fetched at bare,
   unstamped URLs. Cloudflare overrides the origin's Cache-Control and served
   them with max-age=14400, so a change to shell.css could sit up to four
   hours stale on a device whose theme.css was already fresh. That is exactly
   what happened to P47.5: navigation.css arrived and sized the strip to 48dp
   while the operator's shell.css still had no min-height on the wa anchor, so
   he measured a 14.7px target inside a 48px strip. They are now linked from
   the templates with ?v={{ asset_v }} like every other stylesheet, ahead of
   theme.css so the cascade order is unchanged. */
/* ============================================================
 * PHNTM Azul - shared theme + responsive layer
 * ============================================================
 * Loaded after the inline <style> blocks in each template, so
 * its media queries and theme-toggle overrides win when they
 * disagree. Keep this file tight: only cross-cutting concerns.
 * ----------------------------------------------------------- */

/* ---------- Kill browser visited-link purple ----------
   The PHNTM headers wrap their title block in <a href="/"> for a
   "click to go home" affordance. Browsers paint visited links purple
   (#551A8B). This kept leaking through h1's that inherit the link's
   color. Force every header link to inherit text color instead.
   ARKHM | 2026-05-13 - Phase 0.8 */
a.title-block, a.title-block:visited,
a.title-block h1, a.title-block:visited h1,
a.title-block .label, a.title-block:visited .label,
header .left, header .left:visited,
header .left h1, header .left:visited h1,
header .left .label, header .left:visited .label,
.hub-header a, .hub-header a:visited,
.chat-header a, .chat-header a:visited {
  color: inherit !important;
}
/* But keep the label azul and the title in text color */
header .title-block .label,
header .left .label { color: var(--azul) !important; }
header .title-block h1,
header .left h1 { color: var(--text) !important; }

/* ---------- Light theme variables (override by data-theme="light" on <html>) ---------- */

html[data-theme="light"] {
  --bg: #f3f5f8;
  --overlay-wash: #ffffff;
  --overlay-wash2: #ebefe9;
  --border: #d4dbcf;
  --border-bright: #adb8c2;
  --azul: #0a5fb8;            /* darker again: #0a66c2 measured 4.33:1 on a tinted chip */
  --azul-dim: #6b85a8;
  --azul-muted: #a8c6e4;
  --amber: #8a6100;   /* was #b07a10, 3.73:1 on the light page */
  --red: #b3261e;
  --text: #1a222a;
  --text-muted: #56636e;
  --text-dim: #5c6b78;
  /* Legacy aliases */
  --accent: var(--azul);
  --accent2: var(--azul);
  --green: var(--azul);
}

html[data-theme="light"] body::before {
  /* Lighten the grid overlay too */
  background-image:
    linear-gradient(rgba(6, 85, 164, 0.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(6, 85, 164, 0.04) 1px, transparent 1px) !important;
}

/* ---------- A1 LIGHT BODY ----------
   shell.css sets `html body { background: linear-gradient(155deg, #0a0d0c,
   #0d1010) }` at specificity (0,0,2), which beats every template's own
   `body { background: var(--bg) }` at (0,0,1). Nothing overrode it for
   light mode, so light mode flipped every token correctly and left the page
   black underneath. This selector is (0,1,2) and wins.

   Values are the light --bg #f3f5f8 carried through the same 155deg two-stop
   shape as the dark gradient, so the two themes have the same form and only
   the lightness is inverted. #edf0f5 against --text #1a2a1e measures 14.6:1.
   ARKHM | MK.V.136 */
html[data-theme="light"] body {
  background: linear-gradient(155deg, #f5f7fa 0%, #edf0f5 100%);
  background-attachment: fixed;
}


html[data-theme="light"] header {
  background: rgba(244, 246, 243, 0.92) !important;
}

html[data-theme="light"] .summary-content code {
  background: var(--overlay-wash2);
  color: var(--azul);
}

html[data-theme="light"] input[type="text"],
html[data-theme="light"] input[type="datetime-local"],
html[data-theme="light"] textarea,
html[data-theme="light"] select,
html[data-theme="light"] .speaker-input,
html[data-theme="light"] .speaker-role {
  background: var(--overlay-wash);
  color: var(--text);
  border-color: var(--border);
}

html[data-theme="light"] .summary-textarea {
  background: var(--overlay-wash);
  color: var(--text);
}

/* ---------- Theme toggle button ---------- */

.theme-toggle {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted);
  width: 32px;
  height: 32px;
  border-radius: 2px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 14px;
  transition: border-color 0.12s, color 0.12s;
  margin-right: 0.75rem;
  padding: 0;
}
.theme-toggle:hover {
  border-color: var(--azul);
  color: var(--azul);
}

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

/* Tablet */
@media (max-width: 1199px) {
  main { padding: 1.25rem !important; }
  header { padding: 0 1rem !important; }
  .header-meta { font-size: max(0.6rem, var(--fs-floor)) !important; gap: 0.75rem !important; }
}

/* Phone */
@media (max-width: 1199px) {
  /* Header: stack tighter */
  header {
    height: auto !important;
    min-height: 56px;
    padding: 0.5rem 0.75rem !important;
    flex-wrap: wrap;
    gap: 0.4rem;
  }
  .header-logo img { height: 32px !important; }
  .header-meta {
    font-size: max(0.55rem, var(--fs-floor)) !important;
    gap: 0.5rem !important;
    flex-wrap: wrap;
  }
  .header-meta span:not(:first-child) { display: none; }

  /* Main content padding */
  main { padding: 0.75rem !important; }

  /* Section labels - tighter */
  .section-label {
    font-size: max(0.55rem, var(--fs-floor)) !important;
    letter-spacing: 0.15em !important;
  }

  /* Upload zone - smaller padding, smaller text */
  .upload-zone {
    padding: 1.5rem 0.75rem !important;
  }
  .upload-zone h3 {
    font-size: max(0.7rem, var(--fs-floor)) !important;
    letter-spacing: 0.18em !important;
  }
  .upload-zone p {
    font-size: max(0.65rem, var(--fs-floor)) !important;
    word-break: break-word;
  }

  /* Upload meta - wraps */
  .upload-meta {
    flex-direction: column;
    align-items: flex-start !important;
    gap: 0.5rem !important;
  }

  /* Recording cards - give them room */
  .recording-card {
    flex-wrap: wrap;
    padding: 0.75rem 0.9rem !important;
    gap: 0.5rem !important;
  }
  .recording-name {
    flex-basis: 100%;
    font-size: 0.85rem !important;
  }
  .recording-meta {
    flex-wrap: wrap;
    gap: 0.4rem !important;
  }
  .tag, .recording-date, .status-badge { font-size: max(0.55rem, var(--fs-floor)) !important; }

  /* Recording detail title */
  .rec-name { font-size: 1.1rem !important; line-height: 1.3 !important; }

  /* Meeting-type tabs - scrollable horizontal strip */
  .type-selector {
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    padding-bottom: 0.5rem;
    -webkit-overflow-scrolling: touch;
    gap: 0.35rem !important;
  }
  .type-btn { white-space: nowrap !important; flex: 0 0 auto !important; font-size: max(0.6rem, var(--fs-floor)) !important; }

  /* Confirm panel - fewer columns */
  .input-row { flex-direction: column !important; gap: 0.5rem !important; }
  .input-row input { min-width: 0 !important; width: 100% !important; }
  .input-row .btn { width: 100%; }
  .candidate-btn { padding: 0.75rem !important; }

  /* Summary content - slightly smaller text */
  .summary-content { font-size: 0.875rem !important; }
  .summary-content h2 { font-size: 1rem !important; }
  .summary-content h3 { font-size: 0.9rem !important; }

  /* Action items - vertical priority chip */
  .action-row {
    grid-template-columns: 22px 1fr !important;
  }
  .action-priority-chip { display: none; }

  /* Transcript - collapse to single column, speaker stacks above text */
  .tx-line {
    grid-template-columns: 60px 1fr !important;
    grid-template-rows: auto auto;
    gap: 0.3rem 0.6rem !important;
    padding: 0.4rem 0.5rem 0.4rem 0.65rem !important;
  }
  .tx-spk {
    grid-column: 1 / -1;
    font-size: max(0.6rem, var(--fs-floor)) !important;
  }
  .tx-ts {
    grid-row: 2;
  }
  .tx-text {
    grid-row: 2;
    font-size: 0.78rem !important;
  }

  /* Audio player full width */
  audio { width: 100% !important; }

  /* Speaker legend wraps cleanly */
  .speaker-legend { gap: 0.35rem !important; }
  .speaker-chip { font-size: max(0.55rem, var(--fs-floor)) !important; padding: 0.2rem 0.5rem !important; }

  /* Bottom action bar wraps */
  .actions-bar {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 0.5rem !important;
  }
  .actions-bar .btn { width: 100% !important; justify-content: center; }

  /* Speaker assignment grid - single column */
  .speaker-row {
    grid-template-columns: 1fr !important;
    gap: 0.4rem !important;
  }
  .speaker-label { text-align: left !important; }

  /* Queue badge - smaller */
  .phntm-queue-badge { font-size: max(0.55rem, var(--fs-floor)) !important; padding: 0.3rem 0.5rem !important; }
  .phntm-queue-popover {
    min-width: 280px !important;
    max-width: 95vw !important;
  }

  /* Status bar at the bottom - hide segments to save space */
  .status-bar .segments { display: none; }
  .status-bar { font-size: max(0.55rem, var(--fs-floor)) !important; padding: 0.5rem 1rem !important; }
}

/* Very narrow phones */
@media (max-width: 599px) {
  .upload-zone .upload-glyph { font-size: 1rem !important; }
  .header-meta .dot { display: none; }
  .header-meta span { font-size: max(0.5rem, var(--fs-floor)) !important; }
}

/* ============================================================
   Mobile pass 2  -  fixes from operator screenshots
   ARKHM | 2026-05-13
   - Archive cards clipping horizontally
   - Jump-to-top/bottom buttons covering transcript text
   - Default audio player too tall on mobile
   - Speaker grid header still trying 3-col under stacked inputs
   - "CONFIRM & APPLY NAMES" button text wrapping vertically
   ============================================================ */
@media (max-width: 1199px) {
  /* Kill horizontal overflow at the root  -  any wider child gets clipped
     instead of scrolling the whole page sideways. */
  html, body { overflow-x: hidden !important; max-width: 100vw; }
  main, .app, .container { max-width: 100% !important; overflow-x: hidden; }

  /* Recording cards in the archive  -  guarantee they fit the viewport */
  .recording-card {
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
    box-sizing: border-box;
  }
  .recording-card .recording-name,
  .recording-card .meta-row,
  .recording-card > * { min-width: 0 !important; }

  /* Hide the floating jump-to-top/bottom buttons on mobile  -  they
     covered the right edge of transcript text. Native scroll is fine. */
  .jump-btn { display: none !important; }

  /* Default <audio> control is way too tall on phones  -  constrain it */
  audio {
    height: 36px !important;
    width: 100% !important;
    max-width: 100% !important;
  }

  /* Speaker assignment grid header (Label / Real Name / Role)  -  hide
     on mobile since the inputs themselves collapse to one column and
     their placeholders carry the labeling. */
  .speaker-grid-header { display: none !important; }

  /* Speaker confirm bar  -  was a flex row that crushed the button into
     a narrow column, forcing its text to wrap into "CONFIRM / & APPLY /
     NAMES". Stack the button above its description instead. */
  .speaker-confirm-bar {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 0.6rem !important;
  }
  .speaker-confirm-bar .btn,
  .speaker-confirm-bar button {
    width: 100% !important;
    white-space: nowrap !important;
    padding: 0.75rem 1rem !important;
    font-size: 0.75rem !important;
  }
  .speaker-confirm-bar span { font-size: max(0.72rem, var(--fs-floor)) !important; }

  /* General  -  any button whose label is short shouldn't wrap */
  .btn-accent { white-space: nowrap; }
}

/* ============================================================
 * Fluid motion - global polish (ARKHM | 2026-05-25)
 * GPU-friendly transitions + tactile feedback, app-wide. All
 * gated behind prefers-reduced-motion for accessibility.
 * ----------------------------------------------------------- */
@keyframes phntm-fade-in-up { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes phntm-fade-in { from { opacity: 0; } to { opacity: 1; } }

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
  a, button, .btn, .tile, .pill, .tag, input, select, textarea, summary {
    transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease,
                box-shadow 0.18s ease, transform 0.15s ease, opacity 0.15s ease;
  }
  .tile:hover { transform: translateY(-3px); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35); }
  .btn:hover { transform: translateY(-1px); }
  .btn:active, button:active { transform: translateY(0) scale(0.98); }
  /* Hub tiles / panels ease in on load */
  .tile { animation: phntm-fade-in-up 0.34s ease both; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================
 * P17.15 — microinteractions (subtle, operator-tactical not playful)
 * Light global pass: transitions, hover lift, active compress,
 * keyboard-only focus rings. Reference: Linear / Stripe / Vercel.
 * ============================================================ */
button, .btn, a.btn, [role="button"], .tile, .card, .item,
.person-card, .recording-card, .sc-card, .cm-opt, .om-opt {
  transition: background-color 150ms ease, border-color 150ms ease,
              color 150ms ease, box-shadow 150ms ease, transform 100ms ease;
}
/* Active compress on click for actual controls (not large cards). */
button:active, .btn:active, a.btn:active, [role="button"]:active { transform: scale(0.98); }
/* Keyboard-only focus ring — invisible on mouse click, visible on Tab. */
:focus-visible {
  outline: 2px solid var(--azul, #2e9bff);
  outline-offset: 2px; border-radius: 3px;
}
/* Mouse focus (not keyboard) shows no ring, matching pro apps. */
:focus:not(:focus-visible) { outline: none; }
/* Card hover: a single sage border-color shift (not border + bg both). */
.person-card:hover, .recording-card:hover, .item:hover,
.tile:hover, .sc-card:hover { border-color: var(--azul-dim, #3f5468); }
/* Form labels shift sage when their control is focused (where wrapped). */
label:focus-within { color: var(--azul, #2e9bff); }
@media (prefers-reduced-motion: reduce) {
  button, .btn, a.btn, [role="button"], .tile, .card, .item,
  .person-card, .recording-card, .sc-card, .cm-opt, .om-opt { transition: none; }
  button:active, .btn:active, [role="button"]:active { transform: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   P33.4 / P33.5  —  MOBILE FLOORS

   The operator works from a Galaxy Z Fold. Two floors apply below the compact
   breakpoint: no tap target under 44px, no readable text under 12px.

   HOW THE FLOOR WORKS. CSS has no "min-font-size", and a blanket override
   would shrink text that is already large enough. Instead each floor is a
   custom property that is ZERO at desktop and non-zero at compact width, used
   as `max(<original>, var(--fs-floor))`. At desktop max(x, 0) is exactly x, so
   desktop rendering is mathematically unchanged, not merely "probably fine".
   At compact width the value is lifted to the floor. This is what lets 558
   declarations be raised without touching the desktop scale.
   ══════════════════════════════════════════════════════════════════════════ */
:root {
  /* The floor was zero on desktop, so every max(0.5rem, var(--fs-floor))
     in the app rendered at its literal size: the build stamp at 8px, the
     status bar at 8.8px, seventy-eight rules in all. The clamp existed
     and was switched off precisely where the work happens.
     ARKHM | 2026-09-01 */
  --fs-floor: 0.75rem;   /* 12px, every width */
  --tap-floor: 0px;
}

@media (max-width: 599px) {
  :root {
    --fs-floor: 0.75rem;   /* 12px */
    --tap-floor: 44px;
  }

  /* Every control a finger is meant to hit. Applied by element and by the
     naming conventions this codebase already uses for buttons and chips. */
  /* min-height does nothing to a non-replaced inline element, so a link that
     is a control needs a box. Confined to the touch tiers because display is
     not a length and cannot be neutralised by a 0 variable the way the
     sizing above is. */
  a[class]:not(.inline-link),
  nav a, .item a, .card a, .drawer a,
  a.task-link, a.source-link, a.see-all, a.link-action {
    display: inline-flex; align-items: center;
  }

  /* Icon-only controls keep their small glyph for density but grow an
     invisible hit area around it. The pencil on an action item stays a
     19px pencil; the thing your thumb lands on is 44px. */
  .task-edit-btn, .theme-toggle, .qv-btn,
  .tail-toggle, .icon-btn, [class$="-icon-btn"] {
    position: relative;
    min-width: var(--tap-floor);
    min-height: var(--tap-floor);
  }
  /* P37.2: pointer-events: none is not optional here. These overlays are
     44x44 centred on controls as small as 19x17, so they overhang their own
     element by up to 13px on each side and sit over whatever is next to them.
     Without this, paint order decides which control a tap near the boundary
     hits, and the loser is whichever button was painted first. The overlay is
     a visual hit-area affordance; the real target is the element itself, which
     is why min-width and min-height above are what actually make it 44px.
     Those grow the element's own box, so the tap area is real rather than
     borrowed from a neighbour. */
  .task-edit-btn::after, .theme-toggle::after,
  .qv-btn::after, .icon-btn::after {
    content: ""; position: absolute; top: 50%; left: 50%;
    width: var(--tap-floor); height: var(--tap-floor);
    transform: translate(-50%, -50%);
    pointer-events: none;
  }

  /* A 13px checkbox is not a padding problem, it is too small to hit. Give it
     a real control size rather than an expanded miss. */
  input[type="checkbox"], input[type="radio"] {
    width: 22px; height: 22px;
    min-width: 22px; min-height: 22px;
    accent-color: var(--azul, #2e9bff);
    position: relative;
  }
  /* Same reasoning, and worse here: a 44x44 overlay on a 22x22 checkbox
     overhangs 11px on every side, which in a dense list is the row above. The
     checkbox is grown to 22px and given real margin instead; the overlay stays
     purely visual. */
  input[type="checkbox"]::after, input[type="radio"]::after {
    content: ""; position: absolute; top: 50%; left: 50%;
    width: var(--tap-floor); height: var(--tap-floor);
    transform: translate(-50%, -50%);
    pointer-events: none;
  }
  input[type="checkbox"], input[type="radio"] { margin: 11px; }

  /* "See all" was 93 x 11. Inline links that act as buttons need real height. */

}

/* ══════════════════════════════════════════════════════════════════════════
   P33.10  —  THREE TIERS, AND THE FOLD UNFOLDED

   Nineteen ad-hoc width breakpoints collapsed onto three. The tokens below are
   documentation, not machinery: CSS cannot use a custom property inside a
   media query, so the numbers are still written literally. They are recorded
   here so the next person has one place to read the contract instead of
   inferring it from 59 scattered bounds.

       compact   ..480px      Fold cover screen, phones
       medium    481..1024    Fold unfolded, tablets
       wide      1025px..     desktop

   THE FOLD UNFOLDED is the state that was handled worst. At roughly 885 x 800
   it cleared almost every old breakpoint and received the full desktop layout
   inside 800px of height, where desktop layouts assume 1000px or more. Width
   alone cannot detect it: a 900px-wide desktop window is a different problem
   from a 900px-wide device that is only 800px tall. The rule below keys on
   both, so it catches the unfolded Fold and a short laptop window, and leaves
   a genuine desktop alone.
   ══════════════════════════════════════════════════════════════════════════ */
:root {
  --bp-compact: 480px;   /* reference only, see note above */
  --bp-medium: 1024px;
  --bp-wide: 1025px;
}

/* P37.2: THE FLOORS HAVE TO REACH THE SCREEN HE ACTUALLY USES.
   P33 raised --fs-floor and --tap-floor only inside max-width 480. That covers
   the Fold cover screen and the 420-450px Fold 8 Wide cover, but the UNFOLDED
   viewport is about 885 x 800, so the screen he spends most of his time on got
   neither the 12px type floor nor the 44px tap floor. The gate was wrong, not
   the technique: max(x, var(--floor)) needs no change, it just needs the
   variables raised here too.

   Kept as a separate block from the layout rules below so that the floors
   apply to the unfolded Fold regardless of what happens to the layout tuning. */
@media (min-width: 840px) and (max-width: 1199px) and (max-height: 900px) {
  :root {
    --fs-floor: 0.75rem;   /* 12px */
    --tap-floor: 44px;
  }

  /* min-height does nothing to a non-replaced inline element, so a link that
     is a control needs a box. Confined to the touch tiers because display is
     not a length and cannot be neutralised by a 0 variable the way the
     sizing above is. */
  a[class]:not(.inline-link),
  nav a, .item a, .card a, .drawer a,
  a.task-link, a.source-link, a.see-all, a.link-action {
    display: inline-flex; align-items: center;
  }
  .task-edit-btn, .theme-toggle, .qv-btn,
  .tail-toggle, .icon-btn, [class$="-icon-btn"] {
    min-width: var(--tap-floor);
    min-height: var(--tap-floor);
  }
  input[type="checkbox"], input[type="radio"] {
    width: 22px; height: 22px;
    min-width: 22px; min-height: 22px;
    accent-color: var(--azul, #2e9bff);
  }
}

@media (min-width: 840px) and (max-width: 1199px) and (max-height: 900px) {
  /* Vertical space is the scarce resource here, not width. Stop sticky
     furniture from eating a third of an 800px screen. */
  header { height: 52px; position: static; }
  main { padding: 0.75rem 1rem; }

  /* Desktop hero and section spacing assume room this state does not have. */
  .hero, .page-hero { padding: 0.75rem 0 !important; }
  .section-label { margin: 0.6rem 0 0.35rem !important; }

  /* CORTEX gets the same bottom-anchored composer as a phone: the thread
     scrolls, the composer stays reachable. Without this the input floats in
     the middle of a short, wide screen with dead space under it. */
  body.module-cortex .search-wrap {
    display: flex; flex-direction: column;
    height: calc(var(--cortex-vh, 100vh) - 52px);
    margin-bottom: 0;
  }
  body.module-cortex .cortex-thread {
    flex: 1 1 auto; min-height: 0; overflow-y: auto;
  }
  body.module-cortex .cortex-input-row {
    flex: 0 0 auto; position: sticky; bottom: 0; z-index: 5;
    background: var(--bg, #04060a);
    padding-bottom: calc(0.35rem + env(safe-area-inset-bottom, 0px));
  }

  /* Two columns is right for this aspect ratio. Three is cramped, one wastes
     the width the unfolded screen just gained. */
  .tile-grid, .card-grid, .sc-note-list.is-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   P37B  —  THE TAP FLOOR, DEFINED ONCE

   P33.4 put the sizing rules inside each media block, so extending coverage
   meant editing every copy and the Fold block drifted from the compact one.
   Worse, the selector list only knew about buttons and things named -btn, so
   measured misses like a.task-link at 637 x 19.7 and nav drawer links at 36.8
   were never matched at all, and narrow controls like button.del-btn at
   23.1 x 44 got a height floor with no width floor.

   These rules now live OUTSIDE any media query and are gated purely by the
   variables. --tap-floor is 0px at desktop, and min-height: 0 / min-width: 0
   are no-ops, so the wide tier is untouched by construction rather than by
   repetition. One place to add a selector, and the compact and Fold tiers can
   no longer disagree.
   ══════════════════════════════════════════════════════════════════════════ */

/* Controls: both axes. A 23px-wide delete button is as hard to hit as a 19px
   tall one, and only the height was ever floored. */
button, a.btn, .btn, [role="button"], select, summary,
input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
textarea, .chip, [class$="-btn"], [class*="-btn "], [class*="-toggle"],
.action-btn, .qv-btn, .group-rename, .task-edit-btn {
  min-height: var(--tap-floor, 0px);
}
button, a.btn, .btn, [role="button"], select, summary,
[class$="-btn"], [class*="-btn "], [class*="-toggle"],
.action-btn, .qv-btn, .group-rename, .task-edit-btn {
  min-width: var(--tap-floor, 0px);
}

/* Anchors that act as controls. A bare <a> in a sentence must NOT be floored:
   it would tear a paragraph apart. The distinction used here is that a link
   carrying a class, or sitting in a nav, list row or card, was placed as a UI
   element, whereas an unclassed link inside prose is prose. Escape hatch:
   add .inline-link to opt a classed anchor back out. */
a[class]:not(.inline-link),
nav a, .item a, .card a, .drawer a, li > a,
a.task-link, a.source-link, a.see-all, a.link-action {
  min-height: var(--tap-floor, 0px);
}

/* Rows are targets in their own right even when nothing inside them is. */
.item, .recording-card, .person-card, .session-item, .cs-item {
  min-height: var(--tap-floor, 0px);
}

/* MK.VI: the header lockup is an <img>, so CSS cannot recolour its insides.
   Its wordmark is baked at #dde7f2, near-white, and vanished on the light
   page. Swapped for a light twin rather than filtered, because a filter would
   also invert the brand blue. */
html[data-theme="light"] img[src*="phntm-header"] {
  content: url("/static/img/phntm-header-light.svg");
}
