:root {
  --accent: #2e7d32;
  --accent-dark: #235e27;
  --accent-soft: #e7f3e8;
  --accent-contrast: #ffffff;
  --bg: #fafbfa;
  --surface: #ffffff;
  --text: #1a1f1b;
  --text-muted: #667066;
  --border: #e2e7e2;
}

/* Dark palette — applies automatically when the visitor's OS/browser
   prefers dark (unless THEME=light pins it to light), and always when
   THEME=dark pins it explicitly. See lib/brand.js (getThemeAttr) and
   server.js, which set data-theme="light"/"dark" on <html> from the THEME
   env var, or leave it unset for "system" so this media query decides. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --accent: #eb004e;
    --accent-dark: #bc003e;
    --accent-soft: #3a0f1e;
    --accent-contrast: #ffffff;
    --bg: #1a1216;
    --surface: #221a1e;
    --text: #f4ecee;
    --text-muted: #a89aa0;
    --border: #3a2d32;
  }
}

:root[data-theme="dark"] {
  --accent: #eb004e;
  --accent-dark: #bc003e;
  --accent-soft: #3a0f1e;
  --accent-contrast: #ffffff;
  --bg: #1a1216;
  --surface: #221a1e;
  --text: #f4ecee;
  --text-muted: #a89aa0;
  --border: #3a2d32;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: var(--text);
  background: var(--bg);
  line-height: 1.6;
}

a {
  color: var(--accent);
}

.container {
  max-width: 860px;
  margin: 0 auto;
  padding: 0 20px;
}

/* ---- site header ---- */

header.site-header {
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}

header.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 16px;
  padding-bottom: 16px;
}

.brand {
  font-size: 17px;
  font-weight: 700;
  text-decoration: none;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Home page only (index.html) — wraps .brand plus the optional BRAND_TAGLINE
   span so both stay one flex item within the header's own space-between
   layout (header.site-header .container), same as .brand alone was before.
   On every other page the tagline placeholder is never in the markup at
   all, so .brand-wrap there is just an unstyled, harmless wrapper. */
.brand-wrap {
  display: flex;
  align-items: baseline;
  gap: 10px;
  min-width: 0;
}

.brand-tagline {
  font-size: 13px;
  font-weight: 400;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (max-width: 640px) {
  .brand-tagline {
    display: none;
  }
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 18px;
  font-size: 14px;
}

.site-nav a {
  text-decoration: none;
  font-weight: 500;
}

/* :not(.btn) on both of these matters — a plain ".site-nav a" or
   ".site-nav a:hover" selector has higher specificity than ".btn-primary"/
   ".btn-primary:hover" (class+element beats class alone), so without this
   exclusion these would repaint a primary nav button's text back to the
   accent color — the same color as its own background (the "Create
   Account" button bug: accent-on-accent text, in both its default and
   hover states). Excluding .btn here lets button-classed nav links fall
   through entirely to the global .btn/.btn-primary rules below instead.
*/
.site-nav a:not(.btn) {
  color: var(--text-muted);
}

.site-nav a:not(.btn):hover {
  color: var(--accent);
}

.site-nav a.btn:not(.btn-primary) {
  color: var(--accent);
}

/* .user-identity is an <a> even before a username is known (falls back to
   plain email text with its href removed — see dashboard.js renderIdentity)
   so it needs its own not-actually-a-link cursor, since :not(.btn) above
   already colors it like every other nav link regardless of href. */
.user-identity:not([href]) {
  cursor: default;
}

.user-identity:not([href]):hover {
  color: var(--text-muted);
}

/* Hamburger toggle for .site-nav — hidden by default (desktop/tablet width,
   where .site-nav already lays out fine as an inline row) and only shown
   below the breakpoint in the media query further down, which is also where
   .site-nav itself switches from "always visible inline row" to "collapsed
   unless toggled open". app.js's initNavToggle() wires the click. */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}

.nav-toggle:hover {
  border-color: var(--accent);
  color: var(--accent);
}

@media (max-width: 640px) {
  .nav-toggle {
    display: inline-flex;
  }

  /* flex-wrap lets .site-nav (100% width below) drop to its own row under
     the brand+toggle row instead of needing separate absolute positioning —
     there's no page content beside the header for it to overlap either
     way. */
  header.site-header .container {
    flex-wrap: wrap;
  }

  .site-nav {
    display: none;
    width: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
  }

  /* Toggled by app.js's initNavToggle(), not a CSS-only checkbox hack —
     keeping it a plain class match app.js's other nav-state classes
     (nav-logged-out/nav-logged-in) use for the same "[hidden] is the only
     other thing already fighting .btn's `display` here" reason documented
     below. */
  .site-nav.nav-open {
    display: flex;
  }

  /* :not(.btn) so this doesn't fight .btn's own (larger, pill-shaped)
     padding — same reasoning as the a:not(.btn) color rule above this
     media query. */
  .site-nav a:not(.btn) {
    padding: 8px 4px;
  }

  .site-nav a.btn {
    width: 100%;
  }
}

/* The [hidden] attribute is how hydrateSiteNav() (app.js) toggles
   .nav-logged-out/.nav-logged-in — it relies on the browser's default
   `[hidden] { display: none }` UA rule. That default loses to ANY author
   rule that sets `display` on the same element regardless of specificity
   (author styles beat UA styles at equal importance), so `.btn`'s own
   `display: inline-flex` below was silently overriding it — a button-styled
   nav link like "Create Account" (.btn.btn-primary.nav-logged-out) stayed
   visible even while actually hidden="", because the .btn rule, not the
   browser default, was what actually painted it. This reinstates `hidden`
   as authoritative for every element, button-styled or not. */
[hidden] {
  display: none !important;
}

/* ---- buttons ---- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  padding: 10px 18px;
  cursor: pointer;
  text-decoration: none;
  font-family: inherit;
}

.btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
}

.btn-primary:hover {
  background: var(--accent-dark);
  border-color: var(--accent-dark);
  color: var(--accent-contrast);
}

.btn-block {
  width: 100%;
}

/* ---- hero / landing ---- */

.hero {
  padding: 72px 0 56px;
}

.hero h1 {
  font-size: 38px;
  margin: 0 0 14px;
  max-width: 16ch;
}

.hero p.lede {
  font-size: 17px;
  color: var(--text-muted);
  max-width: 52ch;
  margin: 0 0 28px;
}

.hero-actions {
  display: flex;
  gap: 12px;
  margin-bottom: 8px;
}

.how-it-works {
  padding: 8px 0 64px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

@media (max-width: 680px) {
  .how-it-works { grid-template-columns: 1fr; }
}

.how-step {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 20px;
}

.how-step .step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 13px;
  font-weight: 700;
  margin-bottom: 12px;
}

.how-step h3 {
  font-size: 15px;
  margin: 0 0 6px;
}

.how-step p {
  font-size: 13.5px;
  color: var(--text-muted);
  margin: 0;
}

.footnote {
  color: var(--text-muted);
  font-size: 13.5px;
  padding-bottom: 60px;
}

/* ---- support page (/support) ---- */

.support-section {
  max-width: 680px;
  margin: 0 0 36px;
}

.support-section h2 {
  font-size: 18px;
  margin: 0 0 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}

.support-section h3 {
  font-size: 14.5px;
  margin: 20px 0 6px;
}

.support-section p,
.support-section li {
  font-size: 14px;
  color: var(--text-muted);
}

.support-section ul {
  padding-left: 20px;
  margin: 0;
}

.support-section li {
  margin-bottom: 8px;
}

/* ---- site footer ---- */

/* Shared across every regular-chrome page (see lib/brand.js's
   getFooterHtml(), spliced in via server.js's {{SITE_FOOTER}} and
   lib/publicPages.js's layout()) — NOT shown on privacy-policy.html or
   terms.html, which are self-contained documents with their own
   single-purpose footer already, or on frame.html, a full-viewport iframe
   viewer with no room for one. */
.site-footer {
  margin-top: 48px;
  border-top: 1px solid var(--border);
  padding: 28px 0 36px;
}

.site-footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* flex-start, not space-between — space-between was spreading the row's
     two groups (nav links, copyright) to the far left and far right edges
     even with only 14px of actual content between them once the window was
     wide, which read as the copyright line floating off on its own rather
     than being part of the same footer. flex-start keeps everything
     clustered together, left-aligned, the same direction .footer-copyright
     itself already reads in. */
  justify-content: flex-start;
  gap: 14px;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
}

.footer-links a {
  color: var(--text-muted);
  text-decoration: none;
  font-size: 13.5px;
}

.footer-links a:hover {
  color: var(--text);
  text-decoration: underline;
}

/* Shares row 1 with .footer-links, pinned to the far right of it
   (margin-left:auto) — `order: 1` keeps it right after .footer-links'
   default 0 and, crucially, before .footer-copyright's order: 2 below,
   which is what forces the copyright line onto its own row 2 underneath
   this one instead of sharing it. */
.footer-social {
  display: flex;
  gap: 12px;
  order: 1;
  margin-left: auto;
}

.footer-social-link {
  color: var(--text-muted);
  text-decoration: none;
  font-size: 16px;
  line-height: 1;
}

.footer-social-link:hover {
  color: var(--accent);
}

/* Its own row (flex: 1 0 100% forces a line break both before and after it,
   since nothing else can fit alongside a 100%-basis item), always below the
   links/social row above it — order: 2 is only there to make that ordering
   explicit relative to .footer-links (0) and .footer-social (1); the
   flex-basis is what actually creates the row split, at every width, not a
   breakpoint-specific override. */
.footer-copyright {
  color: var(--text-muted);
  font-size: 12.5px;
  margin: 0;
  flex: 1 0 100%;
  order: 2;
}

/* ---- auth forms ---- */

.auth-wrap {
  max-width: 380px;
  margin: 64px auto;
  padding: 0 20px;
}

.auth-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 28px;
}

.auth-card h1 {
  font-size: 21px;
  margin: 0 0 6px;
}

.auth-card .auth-sub {
  color: var(--text-muted);
  font-size: 13.5px;
  margin: 0 0 22px;
}

.field {
  margin-bottom: 14px;
}

.field label {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 5px;
}

.field input,
.field textarea {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 14px;
  font-family: inherit;
}

.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--accent);
}

.field-checkbox {
  margin-bottom: 16px;
}

/* Scoped as ".field-checkbox .checkbox-label" rather than bare
   ".checkbox-label" — this label sits inside a ".field" div (for the
   auth-form's existing field spacing), and plain ".field label" (a class +
   an element = higher specificity than a single class alone) would
   otherwise win and silently override this rule's display/color/weight,
   same class of bug as the nav button fix above. */
.field-checkbox .checkbox-label {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
}

.field-checkbox .checkbox-label input[type="checkbox"] {
  width: auto;
  margin-top: 2px;
  flex: 0 0 auto;
}

.form-error {
  color: #c62828;
  font-size: 13px;
  min-height: 18px;
  margin: -4px 0 10px;
}

.auth-switch {
  text-align: center;
  font-size: 13.5px;
  color: var(--text-muted);
  margin-top: 16px;
}

/* ---- dashboard ---- */

.dash-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 28px 0 20px;
}

.dash-header h1 {
  font-size: 22px;
  margin: 0;
}

.dash-user {
  font-size: 13.5px;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: 12px;
}

.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px 20px;
  margin-bottom: 22px;
}

.panel h2 {
  font-size: 15px;
  margin: 0 0 6px;
}

/* A .panel h2 paired with a same-row control — currently just the
   dashboard's "Your bookmarklet" collapse toggle (dashboard.js's
   setBookmarkletCollapsed()). `.panel h2`'s own bottom margin above is
   overridden to 0 here so the row's cross-axis centering isn't thrown off
   by the heading sitting slightly lower than the button. */
.panel-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.panel-header-row h2 {
  margin: 0;
}

.panel .panel-hint {
  font-size: 13px;
  color: var(--text-muted);
  margin: 0 0 14px;
}

.banner-panel {
  border-color: var(--accent);
  background: var(--accent-soft);
}

/* Admin page — one .admin-slot-card (a .panel) per registered ad slot, see
   public/admin.js's slotCardHtml(). */
.admin-embed-input {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
  font: 13px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  resize: vertical;
  margin-bottom: 10px;
}

.admin-embed-input:focus {
  outline: none;
  border-color: var(--accent);
}

.admin-slot-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  margin-bottom: 14px;
}

.admin-slot-toggle input[type="checkbox"] {
  width: auto;
}

.admin-slot-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.admin-slot-status {
  font-size: 13px;
}

.admin-slot-status-ok {
  color: var(--accent);
}

.admin-slot-status-error {
  color: #c62828;
}

.admin-slot-updated {
  font-size: 12px;
  color: var(--text-muted);
  margin: 10px 0 0;
}

/* Admin page — the tab bar switching between the Reports and Ad slots
   panels (public/admin.js's tab-click listener). Plain buttons, not real
   `<a href>` tabs — there's nothing to deep-link to, both panels already
   load together, this is purely a same-page show/hide toggle. */
.admin-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 20px;
}

.admin-tab {
  padding: 10px 16px;
  border: none;
  background: none;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px; /* sits flush on top of .admin-tabs' own border */
}

.admin-tab:hover {
  color: var(--text);
}

.admin-tab-active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

/* Admin page — the Reports panel, one .report-card (a .panel) per open (or,
   after the "Show resolved" toggle, resolved) report — see
   public/admin.js's reportCardHtml(). */
.report-card {
  padding: 14px 18px;
}

/* A report flagging content as involving a minor gets a visibly different
   treatment from the rest of the queue — a left accent bar in a distinct
   color, not just the same badge everything else gets — so it can't get
   lost between a run of "Broken or doesn't work" reports waiting their
   turn. This is a queue-ordering aid for an admin, not a moderation
   decision on its own — see lib/reports.js's own comment on why this
   reason exists. */
.report-card-urgent {
  border-left: 3px solid #c62828;
}

.report-card-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}

.report-reason-badge {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 100px;
  background: var(--accent-soft);
  color: var(--accent);
  white-space: nowrap;
}

.report-card-urgent .report-reason-badge {
  background: #fdeaea;
  color: #c62828;
}

.report-meta {
  font-size: 13px;
  color: var(--text-muted);
}

.report-note {
  font-size: 13.5px;
  margin: 0 0 12px;
  padding: 10px 12px;
  background: var(--bg);
  border-radius: 8px;
}

.report-card-actions {
  display: flex;
  align-items: center;
}

.report-resolved-label {
  font-size: 13px;
  color: var(--text-muted);
}

.text-muted {
  color: var(--text-muted);
}

.username-form {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.username-form input {
  flex: 1 1 220px;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 14px;
  font-family: inherit;
}

.username-form input:focus {
  outline: none;
  border-color: var(--accent);
}

.bookmarklet-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.bookmarklet-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--accent-soft);
  color: var(--accent-dark);
  border: 1px dashed var(--accent);
  border-radius: 8px;
  padding: 9px 16px;
  font-size: 13.5px;
  font-weight: 700;
  text-decoration: none;
  cursor: grab;
  user-select: none;
}

.bookmarklet-regenerate {
  font-size: 12.5px;
  color: var(--text-muted);
  background: none;
  border: none;
  cursor: pointer;
  text-decoration: underline;
  font-family: inherit;
  padding: 0;
}

.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 16px;
}

.toolbar input[type="text"] {
  flex: 1;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 14px;
}

.toolbar input[type="text"]:focus {
  outline: none;
  border-color: var(--accent);
}

/* Activity page's three modules (public/activity.html/js) — a plain button
   row, not a full tab widget: activity.js toggles which .activity-panel is
   hidden and which button carries aria-selected="true", styled here purely
   off that attribute rather than a separate "active" class so the two can
   never drift out of sync with each other. */
.activity-tabs {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--border);
}

.activity-tab {
  padding: 10px 16px;
  border: none;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--text-muted);
  font-size: 14px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
}

.activity-tab:hover {
  color: var(--text);
}

.activity-tab[aria-selected="true"] {
  color: var(--text);
  border-bottom-color: var(--accent);
}

.count {
  color: var(--text-muted);
  font-size: 13px;
  margin-bottom: 12px;
}

.list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.row {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.row-main {
  flex: 1;
  min-width: 0;
}

.row-title-line {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.row-favicon {
  width: 16px;
  height: 16px;
  border-radius: 3px;
  flex: 0 0 auto;
}

.row-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.row-title:hover {
  text-decoration: underline;
}

.row-sitename {
  font-size: 11.5px;
  color: var(--text-muted);
  background: var(--accent-soft);
  padding: 1px 6px;
  border-radius: 999px;
  flex: 0 0 auto;
}

/* View counter — shown on the dashboard's own rows (next to the title,
   since there's no meta/date line there to fold into) and on the public
   /browse row list and /bookmark/:id permalink page (browse.css's
   .row-meta/.bm-meta, which this inherits its muted/small look from). See
   lib/views.js for why this is per-bookmark, not shared across every
   bookmark row for the same URL the way vote scores are. */
.row-views {
  font-size: 11.5px;
  color: var(--text-muted);
  flex: 0 0 auto;
  white-space: nowrap;
}

.row-url-line {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  margin: 2px 0 8px;
}

.row-url {
  font-size: 12px;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.row-description {
  font-size: 12.5px;
  color: var(--text-muted);
  margin: 0 0 8px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.row-thumb {
  width: 72px;
  height: 72px;
  object-fit: cover;
  border-radius: 8px;
  flex: 0 0 auto;
  border: 1px solid var(--border);
}

.row-tags,
.row-notes {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 5px 8px;
  font-size: 12.5px;
  font-family: inherit;
  margin-top: 4px;
  resize: vertical;
}

.row-tags:focus,
.row-notes:focus {
  outline: none;
  border-color: var(--accent);
}

/* .tag-pill lives here (not browse.css) because the dashboard's read/edit
   tag display (server/public/dashboard.js) reuses the exact same look as
   the public pages' clickable tag pills — both are links now: the public
   ones go to /tag/NAME, the dashboard's own filter its own list in place
   (see dashboard.js's setActiveTag) since a dashboard row can be private
   and has no public /tag/NAME page to send you to. One visual style,
   shared by both contexts. */
.tag-pill {
  display: inline-block;
  background: var(--accent-soft);
  color: var(--accent-dark);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
  margin: 2px 4px 2px 0;
}

.tag-pill:hover {
  background: var(--accent);
  color: var(--accent-contrast);
}

/* .tag-banner also lives here (not browse.css) for the same reason as
   .tag-pill above — the dashboard's own tag filter (dashboard.js) reuses
   this exact "Filtered/Tagged #X ✕ clear" banner look, not just the public
   /tag/NAME and /bookmark/:id pages (browse.js / lib/publicPages.js). */
.tag-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--accent-soft);
  color: var(--accent-dark);
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 14px;
  font-size: 13.5px;
}

.tag-banner-clear {
  color: var(--accent-dark);
  font-weight: 600;
  text-decoration: none;
}

.tag-banner-clear:hover {
  text-decoration: underline;
}

/* Dashboard-only: each editable field (tags, notes) defaults to a compact
   read display (pills / plain text) with a small "Edit" toggle, rather than
   always showing the raw input/textarea the way this row used to. Clicking
   the toggle swaps that one field's display <-> input and flips the
   toggle's own label between "Edit"/"Done" — see dashboard.js's
   wireFieldToggle(). */
.row-field {
  margin-top: 6px;
}

.row-field-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.row-field-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  font-weight: 700;
}

.row-field-edit {
  background: none;
  border: none;
  color: var(--accent);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  padding: 0;
  font-family: inherit;
}

.row-field-edit:hover {
  text-decoration: underline;
}

.row-tags-display {
  margin-top: 3px;
}

.row-notes-display {
  margin: 3px 0 0;
  font-size: 12.5px;
  color: var(--text);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.row-field-empty {
  color: var(--text-muted);
  font-style: italic;
}

.row-visibility {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  width: fit-content;
}

.row-visibility input[type="checkbox"] {
  width: auto;
  margin: 0;
}

.row-delete {
  background: none;
  border: none;
  color: #bbb;
  font-size: 14px;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 6px;
}

.row-delete:hover {
  color: #fff;
  background: #c62828;
}

.empty {
  color: var(--text-muted);
  text-align: center;
  padding: 40px 0;
}
