/* DisPindable Direction B — "Crafted" tokens
 *
 * v0.14.56: layered ON TOP of Pico CSS v2. Loaded conditionally when
 * the user's ui_variant setting is "crafted" (set in Settings →
 * Preferences). Default ui_variant is "classic" which doesn't load
 * this file at all and the app keeps Pico's stock look.
 *
 * Two :root scopes here: the first for light, the second overrides
 * for dark. Pico flips between them via the data-theme attribute on
 * <html>, which the app already toggles via its theme switcher.
 *
 * What this file does:
 *   1. Defines a `--dp-*` token layer that any new template can use
 *   2. Overrides the relevant Pico `--pico-*` variables so every
 *      Pico-styled element (buttons, links, body bg, borders) picks
 *      up the new palette without us having to touch any template
 *
 * Source: Direction B handoff (HANDOFF.md + README.md). Palette is
 * "warm cream paper / ink-navy / gold accent / sage / brick".
 */

:root {
  /* === Direction B tokens (light) === */
  --dp-paper:           #FBF8F1;
  --dp-paper-2:         #F2EDE0;
  --dp-ink:             #102640;
  --dp-ink-soft:        #3a4c63;
  /* v0.15.84: was #7a8497 (3.55:1 vs paper — failed WCAG AA 4.5:1).
     Bumped to #5e6878 which hits 5.31:1, comfortably above AA for
     normal-size text. Affects every Pico --pico-muted-color usage
     since this token feeds that override below. */
  --dp-mute:            #5e6878;
  --dp-gold:            #C9A24A;
  --dp-gold-bg:         rgba(201, 162, 74, 0.16);
  --dp-sage:            #5d8a5b;
  --dp-sage-bg:         rgba(93, 138, 91, 0.14);
  --dp-brick:           #B14237;
  --dp-brick-bg:        rgba(177, 66, 55, 0.10);
  /* v0.15.84: was #E4DCC6 (1.29:1 vs paper — borders nearly
     invisible). Bumped to a darker cream that hits 1.7:1, reads as
     a definite edge without overpowering. Pure aesthetic — borders
     don't need WCAG contrast since they're decoration not text. */
  --dp-border:          #CFC09C;
  --dp-border-strong:   #B19D6E;
  --dp-card:            #ffffff;
  --dp-card-sub:        #FBF8F1;
  --dp-shadow-card:     0 1px 0 rgba(16, 38, 64, 0.04);
  --dp-shadow-hero:     0 6px 24px rgba(16, 38, 64, 0.18);

  /* === v0.15.84: semantic accent palette ===
   *
   * Previously every panel set its own arbitrary left-border color
   * inline: teal for visual-auth, purple for AI confidence + history,
   * red for eBay, amber for follow-up + warnings, blue for catalog
   * cross-reference, green for success. The mapping was consistent in
   * practice but not documented; any new panel had to be eyeballed.
   *
   * These tokens make the meaning explicit. Templates can adopt
   * incrementally: anything still using inline hex still works, but
   * new panels should use these so the semantic meaning is clear at
   * a glance.
   *
   * Color choices: each light-mode accent is dark enough to pass
   * WCAG AA (4.5:1) against the cream paper bg, so the same color
   * works both as a left-border accent and as a section-header
   * text color. Dark-mode variants are brighter to read on the
   * navy paper bg. --bg variants are translucent fills sized for
   * tinted-card backgrounds.
   */
  --dp-accent-info:        #2E66C1;  /* catalog, cross-reference, links */
  --dp-accent-info-bg:     rgba(46,102,193,0.08);
  --dp-accent-success:     #226d3e;  /* completed, verified, owned */
  --dp-accent-success-bg:  rgba(34,109,62,0.10);
  --dp-accent-warn:        #866F18;  /* follow-up flag, needs review */
  --dp-accent-warn-bg:     rgba(134,111,24,0.12);
  --dp-accent-danger:      #a01515;  /* errors, fake, delete */
  --dp-accent-danger-bg:   rgba(160,21,21,0.08);
  --dp-accent-ai:          #5a4fcf;  /* AI providers, embeddings */
  --dp-accent-ai-bg:       rgba(90,79,207,0.06);
  --dp-accent-auth:        #6a2eb9;  /* authenticity checks */
  --dp-accent-auth-bg:     rgba(106,46,185,0.06);
  --dp-accent-ebay:        #BB1F25;  /* eBay-branded sections */
  --dp-accent-ebay-bg:     rgba(187,31,37,0.08);

  /* === Direction B type tokens === */
  --dp-font-display:    'Newsreader', Georgia, 'Times New Roman', serif;
  --dp-font-body:       'Public Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --dp-font-mono:       'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --dp-r-sm:            6px;
  --dp-r-md:            10px;
  --dp-r-lg:            14px;
  --dp-r-pill:          999px;

  /* === Pico variable overrides (light) ===
   * Pico's defaults are blue. We replace its primary + background +
   * border + muted colors so every Pico-styled element picks up the
   * cream-paper palette without touching templates.
   */
  --pico-background-color:               var(--dp-paper);
  --pico-color:                          var(--dp-ink);
  --pico-muted-color:                    var(--dp-mute);
  --pico-muted-border-color:             var(--dp-border);
  --pico-primary:                        var(--dp-gold);
  --pico-primary-hover:                  #b08e3a;
  --pico-primary-focus:                  rgba(201, 162, 74, 0.35);
  --pico-primary-inverse:                var(--dp-ink);
  --pico-secondary:                      var(--dp-ink-soft);
  --pico-secondary-hover:                var(--dp-ink);
  --pico-contrast:                       var(--dp-brick);
  --pico-h1-color:                       var(--dp-ink);
  --pico-h2-color:                       var(--dp-ink);
  --pico-h3-color:                       var(--dp-ink);
  --pico-form-element-background-color:  var(--dp-card);
  --pico-form-element-border-color:      var(--dp-border);
  --pico-form-element-focus-color:       var(--dp-gold);
  --pico-card-background-color:          var(--dp-card);
  --pico-card-border-color:              var(--dp-border);
  --pico-card-sectioning-background-color: var(--dp-paper-2);
  --pico-table-border-color:             var(--dp-border);
  --pico-table-row-stripped-background-color: rgba(201, 162, 74, 0.05);

  /* Body font swap */
  --pico-font-family:                    var(--dp-font-body);
}

[data-theme="dark"] {
  /* === Direction B tokens (dark — "Midnight") === */
  --dp-paper:           #0E1622;
  --dp-paper-2:         #1A2536;
  --dp-ink:             #F4ECD6;
  --dp-ink-soft:        #C8C0AB;
  /* v0.15.84: was #8392A6 (5.73:1 — barely AA). Bumped to #A0AFC3
     for 8.14:1 against the dark navy paper. Reads as clearly muted
     but no longer fades into the bg on phone displays with reduced
     brightness. */
  --dp-mute:            #A0AFC3;
  --dp-gold:            #E9C064;
  --dp-gold-bg:         rgba(233, 192, 100, 0.18);
  --dp-sage:            #7BB573;
  --dp-sage-bg:         rgba(123, 181, 115, 0.16);
  --dp-brick:           #E27264;
  --dp-brick-bg:        rgba(226, 114, 100, 0.16);
  /* v0.15.84: was #26344B (1.45:1) — lifted to a more visible navy
     so panel edges + table rows actually look bordered. */
  --dp-border:          #3A4D6E;
  --dp-border-strong:   #56688A;
  --dp-card:            #1A2536;
  --dp-card-sub:        #0E1622;
  --dp-shadow-card:     0 1px 0 rgba(0, 0, 0, 0.18);
  --dp-shadow-hero:     0 6px 24px rgba(0, 0, 0, 0.40);

  /* === v0.15.84: semantic accent palette (dark)  ===
   * Brighter variants of the light-mode accents tuned to read on the
   * dark-navy paper background. Same semantic mapping as light.
   * Background alpha bumped slightly since dark backgrounds need a
   * bit more saturation to register as a tinted card vs pure dark. */
  --dp-accent-info:        #6FA8FF;
  --dp-accent-info-bg:     rgba(111,168,255,0.10);
  --dp-accent-success:     #5BC97D;
  --dp-accent-success-bg:  rgba(91,201,125,0.12);
  --dp-accent-warn:        #E5A53A;
  --dp-accent-warn-bg:     rgba(229,165,58,0.14);
  --dp-accent-danger:      #E76060;
  --dp-accent-danger-bg:   rgba(231,96,96,0.12);
  --dp-accent-ai:          #8A7DF0;
  --dp-accent-ai-bg:       rgba(138,125,240,0.10);
  --dp-accent-auth:        #A77AE6;
  --dp-accent-auth-bg:     rgba(167,122,230,0.10);
  --dp-accent-ebay:        #FF6064;
  --dp-accent-ebay-bg:     rgba(255,96,100,0.10);

  /* Pico dark override layer */
  --pico-background-color:               var(--dp-paper);
  --pico-color:                          var(--dp-ink);
  --pico-muted-color:                    var(--dp-mute);
  --pico-muted-border-color:             var(--dp-border);
  --pico-primary:                        var(--dp-gold);
  --pico-primary-hover:                  #f5cc70;
  --pico-primary-focus:                  rgba(233, 192, 100, 0.4);
  --pico-primary-inverse:                #0E1622;
  --pico-form-element-background-color:  var(--dp-paper-2);
  --pico-form-element-border-color:      var(--dp-border);
  --pico-card-background-color:          var(--dp-card);
  --pico-card-border-color:              var(--dp-border);
  --pico-card-sectioning-background-color: var(--dp-paper-2);
  --pico-table-border-color:             var(--dp-border);
}

/* === Typography: serif for display, mono for section labels === */

/* v0.14.61: explicitly set html + body background to paper. The
 * --pico-background-color override in :root SHOULD have propagated
 * via Pico's `body { background-color: var(--pico-background-color) }`
 * rule, but in practice Pico v2 has `@media (prefers-color-scheme: light)`
 * rules with higher specificity that win when the user's OS prefers
 * light. Explicit selector wins. Also covers main/article in case
 * they ever get bg-color from somewhere. */
html, body {
  background-color: var(--dp-paper) !important;
  color: var(--dp-ink);
}
main { background-color: transparent; }

body { font-family: var(--dp-font-body); }
h1, h2, h3, h4 {
  font-family: var(--dp-font-display);
  font-weight: 500;
  letter-spacing: -0.015em;
}
h1 { font-weight: 400; letter-spacing: -0.02em; }
code, pre, kbd { font-family: var(--dp-font-mono); }

/* === Reusable component classes ===
 *
 * Templates can adopt these incrementally — anything still using
 * inline styles will still look fine because the Pico overrides
 * already cover bg / text / borders. These classes are for higher-
 * fidelity Direction B treatments (stat cards, pills, flash, etc.).
 */
.dp-card {
  background: var(--dp-card);
  border: 1px solid var(--dp-border);
  border-radius: var(--dp-r-lg);
  padding: 1rem 1.2rem;
  box-shadow: var(--dp-shadow-card);
}
.dp-card-hero {
  background: var(--dp-card);
  border: 1px solid var(--dp-border-strong);
  border-radius: var(--dp-r-lg);
  padding: 1.2rem 1.4rem;
  box-shadow: var(--dp-shadow-hero);
}

.dp-section-label {
  font-family: var(--dp-font-mono);
  font-size: 0.69rem;
  font-weight: 600;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--dp-mute);
}

.dp-stat-value {
  font-family: var(--dp-font-display);
  font-size: 2.25rem;
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1;
  color: var(--dp-ink);
}

.dp-pill {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: var(--dp-r-pill);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.4px;
}
.dp-pill-gold  { background: var(--dp-gold-bg);  color: var(--dp-gold);  }
.dp-pill-sage  { background: var(--dp-sage-bg);  color: var(--dp-sage);  }
.dp-pill-brick { background: var(--dp-brick-bg); color: var(--dp-brick); }
.dp-pill-mute  { background: rgba(127,127,127,0.12); color: var(--dp-mute); }

.dp-flash {
  padding: 0.6rem 0.9rem;
  border-left: 3px solid;
  border-radius: 4px;
  margin: 0.7rem 0;
}
.dp-flash-sage  { background: var(--dp-sage-bg);  border-color: var(--dp-sage);  color: var(--dp-sage);  }
.dp-flash-gold  { background: var(--dp-gold-bg);  border-color: var(--dp-gold);  color: var(--dp-gold);  }
.dp-flash-brick { background: var(--dp-brick-bg); border-color: var(--dp-brick); color: var(--dp-brick); }

/* v0.15.4 / v0.15.6: subtle action-button style.
 *
 * Used on row-of-actions clusters where the default Pico "secondary
 * outline" reads too thin. The class is opt-in (apply alongside or
 * in place of existing button classes) so we can roll it through
 * gradually rather than mass-restyling every button in the app.
 *
 * v0.15.6: switched from filled sage to a subtle ink-soft cream
 * surface that matches the page font palette rather than competing
 * with it. Light theme uses an ink-soft tint, dark theme uses an
 * ink-soft tint on the dark paper. A 1px ink-soft border at low
 * opacity defines the edge without shouting. Sage is kept around
 * (via the .dp-btn-accent modifier) for when we *want* visual
 * weight.
 *
 * Font stack: matches what most modern OSes ship as their UI font.
 * Inter when installed, then the platform default sans-UI. Falls
 * back to Helvetica/Arial on ancient machines. No webfont download.
 */
.dp-btn,
button.dp-btn,
a.dp-btn,
[role="button"].dp-btn,
summary.dp-btn,
summary[role="button"].dp-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.8rem;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI",
               Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1.2;
  /* Subtle cream surface, low-contrast border. Reads as "part of the
   * page" rather than "screaming for attention". */
  background: rgba(244, 236, 214, 0.08);
  border: 1px solid rgba(244, 236, 214, 0.22);
  color: var(--dp-ink, #F4ECD6);
  border-radius: 6px;
  cursor: pointer;
  text-decoration: none;
  /* Pico's `.secondary.outline` sets background-color and color with
   * its own specificity. Force-override only those two to keep the
   * dp-btn surface consistent. */
  background-color: rgba(244, 236, 214, 0.08) !important;
  color: var(--dp-ink, #F4ECD6) !important;
  transition: background-color 0.12s ease, border-color 0.12s ease;
}
.dp-btn:hover,
button.dp-btn:hover,
a.dp-btn:hover,
[role="button"].dp-btn:hover,
summary.dp-btn:hover,
summary[role="button"].dp-btn:hover {
  background: rgba(244, 236, 214, 0.16);
  background-color: rgba(244, 236, 214, 0.16) !important;
  border-color: rgba(244, 236, 214, 0.45);
}
/* Light theme: same idea but with the dark ink color on a light
 * paper background. */
[data-theme="light"] .dp-btn,
[data-theme="light"] button.dp-btn,
[data-theme="light"] a.dp-btn,
[data-theme="light"] [role="button"].dp-btn,
[data-theme="light"] summary.dp-btn {
  background: rgba(58, 76, 99, 0.06);
  background-color: rgba(58, 76, 99, 0.06) !important;
  border-color: rgba(58, 76, 99, 0.22);
  color: var(--dp-ink, #1F2A3A) !important;
}
[data-theme="light"] .dp-btn:hover {
  background: rgba(58, 76, 99, 0.12);
  background-color: rgba(58, 76, 99, 0.12) !important;
  border-color: rgba(58, 76, 99, 0.40);
}

/* Accent variant — for when we want a single Save/CTA button to pop.
 * Sage on both themes. */
.dp-btn.dp-btn-accent,
button.dp-btn.dp-btn-accent,
[role="button"].dp-btn.dp-btn-accent,
summary.dp-btn.dp-btn-accent {
  background: var(--dp-sage);
  background-color: var(--dp-sage) !important;
  border-color: var(--dp-sage);
  color: #0E1622 !important;
}
.dp-btn.dp-btn-accent:hover {
  background: #93c98c;
  background-color: #93c98c !important;
}

/* Destructive variant — for Delete and "are you sure?" actions so
 * visual weight matches sibling dp-btns but color flags danger.
 * Includes summary[role="button"] explicitly because Pico's own
 * summary[role="button"] rule has enough specificity to win over a
 * generic .dp-btn-danger selector. v0.15.6 fix: previously the
 * danger style was getting overridden by the base .dp-btn surface
 * on summary elements. */
.dp-btn.dp-btn-danger,
button.dp-btn.dp-btn-danger,
a.dp-btn.dp-btn-danger,
[role="button"].dp-btn.dp-btn-danger,
summary.dp-btn.dp-btn-danger,
summary[role="button"].dp-btn.dp-btn-danger {
  background: var(--dp-brick, #E27264);
  background-color: var(--dp-brick, #E27264) !important;
  border-color: var(--dp-brick, #E27264);
  color: #0E1622 !important;
}
.dp-btn.dp-btn-danger:hover,
summary.dp-btn.dp-btn-danger:hover {
  background: #e98a7e;
  background-color: #e98a7e !important;
  border-color: #e98a7e;
}
[data-theme="light"] .dp-btn.dp-btn-danger,
[data-theme="light"] summary.dp-btn.dp-btn-danger {
  background: #b04a3c;
  background-color: #b04a3c !important;
  border-color: #b04a3c;
  color: #fff !important;
}
[data-theme="light"] .dp-btn.dp-btn-danger:hover {
  background: #913c30;
  background-color: #913c30 !important;
}

/* Compact variant for inline action rows (thumbnails, table cells).
 * Tightens padding/font for buttons that sit beside text content
 * rather than as page-level CTAs. */
.dp-btn.dp-btn-sm {
  padding: 0.2rem 0.55rem;
  font-size: 0.78rem;
  /* v0.15.15: lock height + line-height so <a role="button">.dp-btn-sm
   * renders at the same vertical size as <button>.dp-btn-sm sitting
   * next to it. Without an explicit height, Pico's base [role="button"]
   * rules (different padding/line-height than its button rule) leak
   * through and make anchors taller than real buttons. Drew flagged
   * this on the pin-detail Lens (anchor) + Delete (button) pair —
   * the Lens was visibly taller. */
  height: 1.65rem;
  line-height: 1;
  box-sizing: border-box;
}

/* v0.15.7: toggle cluster — buttons-in-row with independent panels.
 *
 * Pattern:
 *   <div class="dp-toggle-cluster">
 *     <div class="dp-toggle-cluster-row">
 *       <button class="dp-btn dp-toggle-btn"
 *               data-target="#panel-a" aria-expanded="true">
 *         <span class="dp-when-closed">Show A</span>
 *         <span class="dp-when-open">Hide A</span>
 *       </button>
 *       <button class="dp-btn dp-toggle-btn"
 *               data-target="#panel-b" aria-expanded="false"> ... </button>
 *       <button class="dp-btn dp-btn-danger dp-toggle-btn"
 *               data-target="#panel-c" aria-expanded="false"> ... </button>
 *     </div>
 *     <div id="panel-a" class="dp-toggle-panel" data-open="true"> ... </div>
 *     <div id="panel-b" class="dp-toggle-panel"> ... </div>
 *     <div id="panel-c" class="dp-toggle-panel"> ... </div>
 *   </div>
 *
 * The buttons ALWAYS stay in their row regardless of which panel is
 * open. Panels open independently, take full width below the row.
 * Replaces the v0.15.5 <details> pattern, which forced an open
 * details to span the row and visually drop its siblings.
 *
 * Panels are siblings of the row, not children of the buttons —
 * so each can open/close without affecting button placement.
 * Tiny JS (in base.html) wires the click handlers and toggles
 * data-open + aria-expanded. CSS handles the rest.
 *
 * v0.15.9: renamed `.dp-toggle-row` → `.dp-toggle-cluster-row` to
 * avoid colliding with the older settings-page toggle-row class
 * lower in this file (which uses `!important` and was winning the
 * cascade — the series buttons were rendering with the settings
 * class's `grid-template-columns: auto 1fr` instead of my intended
 * 3-equal-columns layout).
 */
.dp-toggle-cluster {
  margin-bottom: 1rem;
}
.dp-toggle-cluster-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.6rem;
  margin-bottom: 0.6rem;
}
@media (max-width: 700px) {
  .dp-toggle-cluster-row { grid-template-columns: 1fr; }
}
.dp-toggle-btn .dp-when-open,
.dp-toggle-btn .dp-when-closed {
  display: none;
}
.dp-toggle-btn[aria-expanded="true"] .dp-when-open {
  display: inline;
}
.dp-toggle-btn[aria-expanded="false"] .dp-when-closed {
  display: inline;
}
/* Chevron on right, rotates 90° when expanded. Hand-rolled via
 * ::after so we don't fight Pico's own summary chevron — these are
 * buttons, not summaries, so Pico's summary[role="button"] rule
 * doesn't apply here. One chevron total. */
.dp-toggle-btn {
  position: relative;
  padding-right: 1.8rem;
  justify-content: flex-start;  /* override dp-btn's default centering */
  width: 100%;
}
.dp-toggle-btn::after {
  content: "›";
  position: absolute;
  right: 0.7rem;
  top: 50%;
  transform: translateY(-50%) rotate(0deg);
  transition: transform 0.15s ease;
  font-size: 1.1rem;
  font-weight: 600;
  line-height: 1;
  opacity: 0.7;
}
.dp-toggle-btn[aria-expanded="true"]::after {
  transform: translateY(-50%) rotate(90deg);
}

/* Panels: hidden by default, shown when [data-open="true"]. Visible
 * panels stack vertically below the button row. */
.dp-toggle-panel {
  display: none;
}
.dp-toggle-panel[data-open="true"] {
  display: block;
  /* Slight breathing room between adjacent open panels. */
  margin-bottom: 1rem;
}

/* v0.15.11: <input type="search"> renders a built-in magnifying-glass
 * icon on the left in most browsers (or right-side on iOS Safari).
 * The default text/placeholder offset doesn't account for that icon
 * width, so the placeholder visibly overlaps the icon on the global
 * search bar, /series search, /collections search, and catalog browse.
 * Add a left-padding nudge so text starts cleanly past the icon.
 *
 * v0.15.85: bumped 2rem → 2.8rem. Drew flagged that the icon still
 * crashed into the placeholder text (the leading "n" of "name..."
 * was reading as ".n..." because the icon overlapped). 2.8rem is
 * the same value the /pins template was already trying to set via
 * inline style — but the !important on the rule below was over-
 * riding the inline. Fix once globally rather than chasing per-
 * template padding-left overrides. */
input[type="search"] {
  padding-left: 2.8rem !important;
}
/* Some browsers (Firefox on dark themes) also render the X clear
 * button — leave default right padding alone so it doesn't collide. */

/* v0.15.9: when a summary[role="button"] also has dp-btn, suppress
 * Pico's built-in disclosure chevron. We use this for inline Edit
 * popovers (folders.html row actions) where the chevron is visual
 * noise — the user already knows clicking opens a panel. The
 * .dp-toggle-btn pattern from v0.15.7 renders its own chevron via
 * ::after; this rule keeps plain dp-btn summaries clean. */
summary[role="button"].dp-btn {
  background-image: none !important;
  padding-right: 0.8rem;  /* don't reserve space for the absent chevron */
}
summary[role="button"].dp-btn.dp-toggle-btn {
  /* Toggle-btn variant DOES draw its own ::after chevron and needs
   * the right-padding reservation. Restore it explicitly. */
  padding-right: 1.8rem;
}

/* Belt-and-suspenders: if someone DOES use the old .dp-collapse on
 * a <details>, suppress Pico's automatic chevron so we don't double
 * up. Pico adds its chevron via background-image on the summary
 * itself. */
.dp-collapse > summary[role="button"] {
  background-image: none !important;
}

/* Inline-style left-border panels we already use everywhere get a
 * subtle nudge so they read warmer.
 */
article[style*="border-left"] { background-color: var(--dp-paper-2) !important; }

/* === Page header pattern (Direction B) ===
 * Standard top-of-page block: mono "EYEBROW" label + serif H1 + lede.
 * Apply to any page wrapper: wrap your H1 in <header class="dp-page-header">.
 */
.dp-page-header {
  margin: 0 0 1.4rem 0;
}
.dp-page-header .eyebrow {
  font-family: var(--dp-font-mono);
  font-size: 0.69rem;
  font-weight: 600;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--dp-mute);
  display: block;
  margin-bottom: 0.4rem;
}
.dp-page-header h1 {
  font-family: var(--dp-font-display);
  font-size: 2.1rem;
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin: 0 0 0.5rem 0;
  color: var(--dp-ink);
}
.dp-page-header .lede {
  color: var(--dp-ink-soft);
  margin: 0;
  max-width: 42rem;
  font-size: 0.95rem;
}
.dp-page-header-bar {
  display: flex; align-items: baseline;
  justify-content: space-between; flex-wrap: wrap; gap: 0.6rem;
  margin: 0 0 1rem 0;
}

/* List page helpers — filter/sort row above a grid */
.dp-toolbar {
  display: flex; align-items: center; gap: 0.6rem;
  flex-wrap: wrap;
  padding: 0.5rem 0; margin-bottom: 0.7rem;
  border-bottom: 1px solid var(--dp-border);
}
.dp-toolbar select,
.dp-toolbar input[type="text"],
.dp-toolbar input[type="search"] {
  margin: 0; padding: 0.35rem 0.7rem;
  font-size: 0.88rem;
  border-radius: var(--dp-r-md);
}

/* Standard card grid */
.dp-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.7rem;
}
.dp-card-tile {
  background: var(--dp-card);
  border: 1px solid var(--dp-border);
  border-radius: var(--dp-r-lg);
  padding: 0.9rem;
  text-decoration: none;
  color: inherit;
  display: block;
  transition: transform 0.12s ease, border-color 0.12s ease;
}
.dp-card-tile:hover {
  transform: translateY(-1px);
  border-color: var(--dp-border-strong);
}
.dp-card-tile img {
  width: 100%; aspect-ratio: 1/1; object-fit: cover;
  border-radius: var(--dp-r-md);
  margin-bottom: 0.5rem;
  border: 1px solid var(--dp-border);
}
.dp-card-tile strong {
  font-family: var(--dp-font-display);
  font-weight: 500; font-size: 1rem;
  letter-spacing: -0.005em;
  display: block;
  color: var(--dp-ink);
  line-height: 1.2;
}
.dp-card-tile small {
  color: var(--dp-mute);
  font-size: 0.78rem;
  display: block;
  margin-top: 0.2rem;
}

/* Toggle row (switch + multi-line label). Used in Settings to align
 * a `role="switch"` checkbox next to a label + description block.
 * Markup:
 *   <label class="dp-toggle-row">
 *     <input type="checkbox" role="switch" name="...">
 *     <div>
 *       <span>Main label</span>
 *       <small>Descriptive helper text</small>
 *     </div>
 *   </label>
 */
.dp-toggle-row {
  display: grid !important;
  grid-template-columns: auto 1fr;
  column-gap: 0.8rem;
  row-gap: 0;
  align-items: start;
  margin: 0 0 1rem 0;
  cursor: pointer;
}
.dp-toggle-row > input[role="switch"] {
  margin: 0.15rem 0 0 0 !important;
  align-self: start;
}
.dp-toggle-row > div { min-width: 0; }
.dp-toggle-row > div > span {
  display: block;
  font-weight: 500;
  color: var(--dp-ink);
  line-height: 1.4;
}
.dp-toggle-row > div > small {
  display: block;
  color: var(--dp-mute);
  font-size: 0.82rem;
  margin-top: 0.2rem;
  line-height: 1.45;
}
.dp-toggle-row > div > small code {
  font-size: 0.8rem;
  padding: 0.05rem 0.3rem;
  background: var(--dp-paper-2);
  border-radius: 3px;
}
