/*
 * feedback-portal styles (fp-hki).
 *
 * Extracted verbatim from the inline <style> block in
 * web/templates/layout.gohtml so the page can drop 'unsafe-inline'
 * from CSP style-src-elem.
 *
 * The --brand CSS custom property is set per-request via a single
 * inline style attribute on <body> (sourced from the project's brand
 * color, sanitised by render.brandColor). All other rules are static.
 */

:root {
  --brand: #4f46e5; /* fallback; <body style="--brand: ..."> overrides */
  --bg: #fafafa;
  --surface: #ffffff;
  --text: #18181b;
  --text-muted: #71717a;
  --border: #e4e4e7;
  --border-strong: #d4d4d8;
  --radius: 8px;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.04);
  --shadow: 0 1px 3px rgba(0,0,0,.06), 0 1px 2px rgba(0,0,0,.04);
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
/* Sticky footer: flex column so the .page wrapper grows to fill any
   remaining viewport height on short pages, pinning .site-footer at
   the bottom rather than letting it float halfway up. */
html { min-height: 100%; }
body {
  min-height: 100vh;
  display: flex; flex-direction: column;
  font-family: -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, sans-serif;
  font-size: 14px; line-height: 1.5; color: var(--text); background: var(--bg);
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
a:hover { color: var(--brand); }

/* ---- Header ---- */
.site-header {
  position: sticky; top: 0; z-index: 10;
  background: var(--surface); border-bottom: 1px solid var(--border);
  padding: 0 1.5rem;
}
.site-header-inner {
  max-width: 1100px; margin: 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  height: 56px; gap: 1rem;
}
.brand-mark {
  font-weight: 700; font-size: 15px; letter-spacing: -.01em;
  color: var(--text); display: flex; align-items: center; gap: .5rem;
}
.brand-mark .dot {
  width: 10px; height: 10px; border-radius: 50%; background: var(--brand);
}
.brand-mark .logo {
  width: 24px; height: 24px; border-radius: 6px; object-fit: cover;
  flex: 0 0 auto;
}
.nav { display: flex; gap: 1.25rem; align-items: center; }
.nav a { font-size: 13px; color: var(--text-muted); font-weight: 500; }
.nav a.active, .nav a:hover { color: var(--text); }

/* ---- Header search (fp-689 / fp-82g) ----
   Lives inside .nav so it shares the nav's flex line. The form
   itself is display: contents so it doesn't add its own box —
   the input becomes a direct flex sibling of the nav links. */
.nav-search { display: contents; }
.nav-search input[type="search"] {
  width: 200px; max-width: 28vw;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px;
  padding: .35rem .6rem; font-size: 13px; line-height: 1.2;
  outline-offset: 2px;
}
.nav-search input[type="search"]:focus {
  border-color: var(--brand);
}

/* ---- Topnav Submit CTA (fp-e9tw) ----
   Pinned to the sticky topbar so the submit affordance is reachable
   on mobile. The board sidebar's .cta-feedback pill stays for desktop
   visual weight; on iPhone-sized viewports it lands ~6000px down the
   page (sidebar reorders below main at the 720px breakpoint), so this
   topnav button is the actual mobile entry point. */
.nav-submit { white-space: nowrap; }
.nav-signin-link { font-size: 13px; }

/* Compact the nav on small viewports so the Submit button stays
   visible alongside Feedback/Roadmap. We drop the search input
   (search is still reachable from the dedicated /search page via
   nav links and post titles) and the secondary Sign-in text link
   (anonymous users still get to the modal via the Submit button or
   the inline "Sign in to post" CTA above the post feed). */
@media (max-width: 640px) {
  .nav { gap: .75rem; }
  .nav-search { display: none; }
  .site-header { padding: 0 1rem; }
  .nav-signin-link { display: none; }
}

/* ---- Search results page (fp-689) ---- */
.search-head { margin-bottom: 1.25rem; }
.search-form {
  display: flex; gap: .5rem; align-items: center;
}
.search-form input[type="search"] {
  flex: 1;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px;
  padding: .55rem .8rem; font-size: 14px;
}
.search-form input[type="search"]:focus { border-color: var(--brand); }
.search-summary {
  color: var(--text-muted); font-size: 13px;
  margin: 0 0 1rem 0;
}
.search-summary strong { color: var(--text); }
.search-notice {
  background: var(--surface); color: var(--text-muted);
  border: 1px solid var(--border); border-radius: 6px;
  padding: .75rem 1rem; margin: 0 0 1.25rem 0; font-size: 13px;
}

.btn {
  background: var(--brand); color: #fff;
  padding: .5rem .9rem; border-radius: var(--radius);
  font-size: 13px; font-weight: 500; border: 0; cursor: pointer;
  display: inline-flex; align-items: center; gap: .35rem;
  transition: opacity .12s;
}
a.btn, a.btn:link, a.btn:visited, a.btn:active { color: #fff; }
.btn:hover, a.btn:hover { opacity: .9; color: #fff; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-ghost {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border-strong);
}
.btn-ghost:hover { background: var(--bg); color: var(--text); }

/* ---- OAuth provider buttons ---- */
.oauth-row {
  display: flex; flex-direction: column; gap: .5rem;
  margin: 0 0 1rem;
}
.oauth-btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: .625rem;
  height: 40px; padding: 0 1rem;
  border-radius: 8px; border: 1px solid transparent;
  font-size: 14px; font-weight: 500;
  text-decoration: none;
  transition: background 120ms, border-color 120ms;
}
.oauth-btn .oauth-logo {
  flex: 0 0 auto;
}
/* Apple: black pill, white text + glyph. HIG-required wording.
   Hover lightens slightly per Apple's spec. */
.oauth-apple, a.oauth-apple, a.oauth-apple:link, a.oauth-apple:visited {
  background: #000; color: #fff; border-color: #000;
}
.oauth-apple:hover { background: #1a1a1a; color: #fff; }
/* Google: white pill, dark text, neutral border. Google's brand
   guidelines forbid the G logo on a colored background. */
.oauth-google, a.oauth-google, a.oauth-google:link, a.oauth-google:visited {
  background: #fff; color: #1f1f1f;
  border-color: #dadce0;
}
.oauth-google:hover { background: #f8f9fa; color: #1f1f1f; }
/* Visible focus for keyboard navigation — Apple/Google buttons
   are anchors so the browser default focus ring would be
   inconsistent with the rest of the form. */
.oauth-btn:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
.oauth-divider {
  display: flex; align-items: center; gap: .75rem;
  margin: 0 0 1rem;
  color: var(--text-muted); font-size: 12px;
}
.oauth-divider::before,
.oauth-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--border);
}

/* ---- Layout: content + right sidebar (UserJot pattern) ---- */
.page {
  flex: 1;
  width: 100%;
  max-width: 1100px; margin: 0 auto; padding: 1.5rem;
  display: grid; grid-template-columns: 1fr 280px; gap: 2.5rem;
}
/* Single column when the page didn't override the sidebar block.
   The aside still renders empty but :empty + display:none drops it
   so the grid track has nothing to size against — combined with
   :has() the page becomes a true single column. */
.page:has(> .sidebar:empty) { grid-template-columns: 1fr; gap: 0; }
.sidebar:empty { display: none; }
@media (max-width: 720px) {
  .page { grid-template-columns: 1fr; padding: 1rem; }
  .sidebar { order: 2; }
}
.sidebar { font-size: 14px; }
.sidebar h3 {
  font-size: 13px; font-weight: 600; margin: 0 0 .5rem; color: var(--text);
}

/* Right-rail "Give Feedback" CTA — bold pill, brand background. */
.cta-feedback {
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  background: var(--brand); color: #fff;
  padding: .85rem 1.25rem; border-radius: 999px;
  font-weight: 600; font-size: 14px; width: 100%;
  margin-bottom: 1.25rem;
  transition: opacity .12s;
}
.cta-feedback:link, .cta-feedback:visited { color: #fff; }
.cta-feedback:hover { opacity: .9; color: #fff; }
.cta-feedback svg { width: 16px; height: 16px; flex: 0 0 auto; }

/* Boxed cards for sidebar meta sections (Status / Posted, Reactions). */
.side-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 1rem 1.1rem;
  margin-bottom: 1rem; font-size: 14px;
}
.side-card .row {
  display: flex; align-items: center; justify-content: space-between;
  padding: .35rem 0;
}
.side-card .label { color: var(--text-muted); }
.side-card .value { color: var(--text); font-weight: 500; }

/* Right-rail Actions block — minimal icon links (just Copy link
   today; Share button removed in fp-h1e for being unreliable). */
.actions-block { margin-top: 1.5rem; }
.actions-block ul { list-style: none; padding: 0; margin: 0; }
.actions-block li { margin: 0; }
.actions-block button {
  display: flex; align-items: center; gap: .65rem;
  padding: .45rem 0; font-size: 13px; font-weight: 500;
  color: var(--text-muted); background: transparent;
  border: 0; cursor: pointer; width: 100%; text-align: left;
}
.actions-block button:hover { color: var(--text); }
.actions-block button:disabled { color: var(--brand); cursor: default; }
.actions-block svg { width: 14px; height: 14px; flex: 0 0 auto; }

/* Top-of-content status filter bar (UserJot pills). */
.status-filters {
  display: flex; align-items: center; gap: 1.5rem;
  padding: 0 0 .85rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 1.5rem;
  font-size: 14px; flex-wrap: wrap;
}
.status-filter {
  display: inline-flex; align-items: center; gap: .45rem;
  color: var(--text-muted); font-weight: 500;
  padding: 0; text-decoration: none;
}
.status-filter:hover { color: var(--text); }
.status-filter.active { color: var(--text); }
.status-filter .ring {
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid currentColor; flex: 0 0 auto;
}
.status-filter .ring.solid { background: currentColor; }
.status-filter.sort {
  margin-left: auto; color: var(--text); border-left: 1px solid var(--border);
  padding-left: 1.5rem;
}

/* Status pill (outlined, colored ring) — used on cards + detail. */
.status-pill {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .25rem .75rem; border-radius: 999px;
  border: 1px solid var(--border-strong);
  font-size: 12px; font-weight: 500; color: var(--text);
  background: var(--surface);
}
.status-pill .ring {
  width: 12px; height: 12px; border-radius: 50%;
  border: 2px solid currentColor; flex: 0 0 auto;
}
/* Color hooks for status rings — keyed to the enum values rendered
   by render/funcs.go (statusPill, statusBadge) and the board filter
   pills in templates. Adding a new status: extend the enum, add a
   row here, and the templates/Go side picks it up automatically. */
/* fp-qhm: palette matches UserJot's roadmap so users moving from
   UserJot see the same status colors. Open kept as sky to disambiguate
   from the new blue Planned (UserJot color). Completed and Shipped both
   green but completed is a lighter shade (done vs released). */
.ring-open { color: #0ea5e9; }        /* sky — pre-roadmap submission */
.ring-pending { color: #f59e0b; }     /* amber — UserJot Pending */
.ring-review { color: #f97316; }      /* orange — UserJot Reviewing */
.ring-planned { color: #3b82f6; }     /* blue — UserJot Planned */
.ring-in-progress { color: #8b5cf6; } /* purple — UserJot In Progress */
.ring-completed { color: #22c55e; }   /* green — done, not released */
.ring-shipped { color: #10b981; }     /* emerald — released */
.ring-closed { color: #64748b; }      /* slate — UserJot Closed */
.ring-verifying { color: #9ca3af; }   /* gray — pending_email (internal) */
.ring-moderating { color: #9ca3af; }  /* gray — pending_moderation (internal) */
.ring-rejected { color: #ef4444; }    /* red — explicit reject */
.ring-neutral { color: #9ca3af; }

/* Status badge (filled pill) — colored background, white text. The
   color hook stays parallel to .ring-* so the two renderers (badge
   and pill) share their palette. */
.badge { color: white; }
.badge-open { background: #0ea5e9; }
.badge-pending { background: #f59e0b; }
.badge-review { background: #f97316; }
.badge-planned { background: #3b82f6; }
.badge-in-progress { background: #8b5cf6; }
.badge-completed { background: #22c55e; }
.badge-shipped { background: #10b981; }
.badge-closed { background: #64748b; }
.badge-verifying { background: #9ca3af; }
.badge-moderating { background: #9ca3af; }
.badge-rejected { background: #ef4444; }
.badge-neutral { background: #9ca3af; }

/* ---- Content cards ---- */
.content > h1 {
  font-size: 22px; font-weight: 600; letter-spacing: -.01em;
  margin: 0 0 .25rem;
}
.content > p.lead {
  color: var(--text-muted); margin: 0 0 1.5rem;
}
.card-list {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
}
.card-list > article { border-top: 1px solid var(--border); padding: 0; }
.card-list > article:first-child { border-top: 0; }

/* Compact variant for the post-detail comment list — padded so the
   nested .comment rows don't run flush against the card border. */
.card-list-padded { padding: 0 1.25rem; }

/* ---- Post card (board feed) ---- */
article.post {
  display: grid; grid-template-columns: 60px 1fr; gap: .9rem;
  padding: 1rem 1.25rem;
  transition: background .12s;
}
article.post:hover { background: rgba(0,0,0,.015); }
article.post .vote-col {
  display: flex; flex-direction: column; align-items: center;
}
article.post h2 {
  margin: 0 0 .15rem; font-size: 14px; font-weight: 600;
  letter-spacing: -.005em;
}
article.post h2 a:hover { color: var(--brand); }
article.post .excerpt {
  color: var(--text-muted); margin: 0 0 .5rem;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
article.post .meta {
  display: flex; gap: .65rem; align-items: center;
  color: var(--text-muted); font-size: 12px;
}
article.post .meta .sep { color: var(--border-strong); }

/* Vertical feed of post.card articles on the board page — replaces
   the inline grid that the htmx target carried. */
.post-feed {
  display: flex; flex-direction: column; gap: 1rem;
}

/* ---- Post detail (UserJot-style: borderless, body-first) ---- */
article.post-detail { padding: 0; background: transparent; border: 0; }
.post-detail-head {
  display: flex; align-items: center; gap: .75rem;
  margin-bottom: 1.5rem;
}
.post-detail-head .author-name { font-weight: 600; font-size: 14px; }
.post-detail-head .author-time {
  color: var(--text-muted); font-size: 13px;
}
.post-detail-body {
  font-size: 22px; line-height: 1.45; letter-spacing: -.005em;
  color: var(--text); margin: 0 0 1.5rem;
  white-space: pre-wrap; word-wrap: break-word;
}
/* The post body paragraph (under the h1) shows as smaller muted text
   so the title carries the primary weight. */
.post-detail-body.body-text {
  font-size: 16px; color: var(--text-muted);
}
.post-detail-meta {
  display: flex; align-items: center; gap: 1rem;
  padding-bottom: 1.25rem; margin-bottom: 1.5rem;
  border-bottom: 1px solid var(--border);
}
.post-detail-meta .vote-heart { margin-left: 0; }

/* ---- Attachments (fp-lp0) ----
   Grid of image thumbnails / file links rendered under the post body.
   Images link to the full-resolution source in a new tab. */
.post-attachments {
  list-style: none; padding: 0; margin: 0 0 1.5rem;
  display: grid; gap: .75rem;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
}
.post-attachment-image img {
  width: 100%; height: auto; max-height: 320px; object-fit: cover;
  border-radius: 8px; border: 1px solid var(--border); display: block;
  background: var(--surface);
}
.post-attachment-image a { display: block; line-height: 0; }
.post-attachment-file {
  padding: .5rem .75rem; border: 1px solid var(--border);
  border-radius: 8px; font-size: 14px; background: var(--surface);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.post-attachment-file a { color: var(--text); text-decoration: none; }
.post-attachment-file a:hover { text-decoration: underline; }

/* ---- Post card thumbnails (fp-sfj) ----
   Single-image strip on the board card. We show at most one image
   to keep cards visually consistent with the existing layout; the
   detail page renders the full gallery. The strip sits between the
   title block and the card foot so it doesn't interfere with the
   card-wide hyperlink. */
.post-card-thumbs {
  display: flex; gap: .375rem; margin: .25rem 0 .75rem;
}
.post-card-thumbs img {
  width: 96px; height: 64px; object-fit: cover;
  border-radius: 6px; border: 1px solid var(--border);
  background: var(--surface);
}
.post-card-thumbs .more {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 32px; padding: 0 .5rem; height: 64px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); color: var(--text-muted);
  font-size: 12px; font-weight: 600;
}

/* ---- Upload zone (fp-sfj / fp-iroa polish) ----
   File picker on the new-post form. The dashed box doubles as a
   drag-and-drop target; .upload-trigger is the visible "Add images"
   button (the native file input is sr-only) and the hint text sits
   next to it. The thumbnail strip grows below as files attach. */
.upload-zone {
  margin: .75rem 0 1rem;
  padding: .85rem 1rem;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface);
  transition: border-color .15s, background .15s;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .5rem .85rem;
}
.upload-zone.upload-busy { opacity: .65; pointer-events: none; }
.upload-zone.upload-dragover {
  border-color: var(--brand);
  border-style: solid;
  background: color-mix(in srgb, var(--brand) 6%, var(--surface));
}

.upload-trigger {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .4rem .75rem;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: var(--radius);
  font-size: 13px; font-weight: 500; cursor: pointer;
  transition: background .12s, border-color .12s, color .12s;
}
.upload-trigger:hover { background: var(--bg); border-color: var(--text-muted); }
.upload-trigger-icon { flex: 0 0 auto; color: var(--text-muted); }
.upload-trigger:hover .upload-trigger-icon { color: var(--text); }
/* Keyboard focus ring lands on the hidden input — mirror it on the
   visible label so tab-users see where they are. */
.upload-input:focus-visible + .upload-trigger-icon {
  outline: 2px solid var(--brand);
  outline-offset: 3px; border-radius: 2px;
}
.upload-trigger:focus-within {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 25%, transparent);
}

.upload-hint {
  color: var(--text-muted); font-size: 12px;
}

/* visually-hidden: removes from layout but keeps in the accessibility
   tree and focus order. Used to hide the native <input type="file">
   while delegating clicks/keyboard to the wrapping label. */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

.upload-attached {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: .5rem;
  flex-basis: 100%;
}
.upload-attached:empty { display: none; }
.upload-thumb {
  position: relative;
  width: 96px; height: 96px;
  border-radius: 6px; overflow: hidden;
  border: 1px solid var(--border); background: var(--surface);
}
.upload-thumb img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.upload-thumb-remove {
  position: absolute; top: 4px; right: 4px;
  width: 22px; height: 22px; padding: 0;
  border: 0; border-radius: 50%;
  background: rgba(0,0,0,.65); color: #fff;
  font-size: 18px; line-height: 1;
  cursor: pointer;
}
.upload-thumb-remove:hover { background: rgba(0,0,0,.85); }
.upload-status {
  margin: 0; font-size: 12px; color: var(--text-muted);
  min-height: 1em; flex-basis: 100%;
}
.upload-status:empty { display: none; }
.upload-status-error { color: #b91c1c; }

/* ---- Reactions card (fp-96s) ---- */
.reactions-card {
  display: flex; align-items: center; gap: .75rem;
  padding: .75rem 1rem; margin-bottom: 1.5rem;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 8px;
}
.reactor-strip {
  list-style: none; padding: 0; margin: 0;
  display: flex; align-items: center;
}
.reactor-strip .reactor {
  margin-left: -6px;
}
.reactor-strip .reactor:first-child { margin-left: 0; }
.reactor-strip .avatar {
  width: 28px; height: 28px;
  border: 2px solid var(--surface);
  background: var(--bg);
  object-fit: cover;
}
.reactions-summary {
  margin: 0; color: var(--text-muted); font-size: 13px;
}
.reactions-summary strong { color: var(--text); font-weight: 600; }

/* ---- Vote button ---- */
.vote-btn {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: 6px;
  padding: .3rem .35rem; min-width: 44px;
  cursor: pointer; font-size: 11px; font-weight: 600;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  transition: border-color .1s, background .1s, color .1s;
}
.vote-btn:hover { border-color: var(--brand); color: var(--brand); }
.vote-btn.voted {
  border-color: var(--brand); background: color-mix(in srgb, var(--brand) 8%, transparent);
  color: var(--brand);
}
.vote-btn .arrow { font-size: 13px; line-height: 1; }
.vote-btn .vote-count { font-size: 12px; line-height: 1; }

/* ---- Status badges (softer / pastel) ---- */
.badge {
  display: inline-block; padding: .15rem .55rem;
  border-radius: 999px; font-size: 11px; font-weight: 500;
  color: white;
}

/* ---- Forms ---- */
form label {
  display: block; margin: 1rem 0 .35rem;
  font-size: 13px; font-weight: 500;
}
form input[type=text], form input[type=email], form textarea {
  width: 100%; padding: .55rem .75rem;
  border: 1px solid var(--border-strong); border-radius: 6px;
  font: inherit; background: var(--surface); color: var(--text);
}
form input:focus, form textarea:focus {
  outline: 2px solid color-mix(in srgb, var(--brand) 40%, transparent);
  outline-offset: 0; border-color: var(--brand);
}
form textarea { min-height: 7rem; resize: vertical; }
form .form-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 1.5rem;
}

/* ---- Comments ---- */
.comments h3 { font-size: 13px; font-weight: 600; margin: 1.5rem 0 .5rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: .05em; }
article.comment {
  padding: .8rem 0; border-top: 1px solid var(--border);
}
article.comment:first-of-type { border-top: 0; }
article.comment p { margin: 0 0 .25rem; }
article.comment footer { color: var(--text-muted); font-size: 12px; }

/* ---- Roadmap (3-column board UserJot-style) ---- */
.roadmap-board {
  display: grid; gap: 2rem;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (max-width: 880px) {
  .roadmap-board { grid-template-columns: 1fr; gap: 1.5rem; }
}
.roadmap-col-v2 { min-width: 0; }
.roadmap-col-title {
  font-size: 20px; font-weight: 600; margin: 0;
  display: flex; align-items: baseline; gap: .55rem;
}
.roadmap-col-title .count {
  color: var(--text-muted); font-weight: 500; font-size: 14px;
}
.roadmap-col-sub {
  color: var(--text-muted); margin: .25rem 0 1.25rem;
  font-size: 14px;
}
.roadmap-cards { display: flex; flex-direction: column; gap: 1rem; }
.roadmap-col-v2 .empty { color: var(--text-muted); font-size: 13px; }

/* ---- Post card (board feed + roadmap columns) ---- */
article.post-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; padding: 1.25rem 1.4rem;
  box-shadow: var(--shadow-sm);
  transition: border-color .12s, box-shadow .12s;
}
article.post-card:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow);
}
.post-card-head {
  display: flex; align-items: center; gap: .55rem;
  margin-bottom: .5rem;
  font-size: 13px;
}
.post-card-head .post-card-author {
  color: var(--text); font-weight: 600;
}
.post-card-cat { color: var(--text-muted); font-size: 13px; }
.category-chip {
  display: inline-flex; align-items: center; gap: .35rem;
  color: var(--text); font-weight: 500;
  margin-left: .15rem;
}
.category-chip .dot {
  width: 8px; height: 8px; border-radius: 50%; display: inline-block;
}
.post-num {
  margin-left: auto;
  color: var(--text-muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}
/* Submit form: native <select> tweaked to match the inputs. */
form select {
  width: 100%; padding: .55rem .75rem;
  border: 1px solid var(--border-strong); border-radius: 6px;
  font: inherit; background: var(--surface); color: var(--text);
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath fill='%236b7280' d='M3 4l3 4 3-4z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .75rem center;
  background-size: 12px;
  padding-right: 2rem;
}
form select:focus {
  outline: 2px solid color-mix(in srgb, var(--brand) 40%, transparent);
  outline-offset: 0; border-color: var(--brand);
}
.post-card-link { display: block; color: inherit; }
.post-card-link:hover { color: inherit; }
article.post-card h3 {
  margin: 0 0 .35rem; font-size: 16px; font-weight: 600;
  line-height: 1.35; letter-spacing: -.005em;
}
article.post-card p {
  margin: 0; color: var(--text-muted); font-size: 14px;
  line-height: 1.55;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}
.post-card-foot {
  display: flex; align-items: center; gap: .85rem;
  margin-top: 1rem;
}
.avatar {
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--bg); color: var(--text-muted);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 600; flex-shrink: 0;
  border: 1px solid var(--border);
}
.post-card-author {
  color: var(--text-muted); font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.vote-heart {
  margin-left: auto;
  background: transparent; border: 0; cursor: pointer;
  display: inline-flex; align-items: center; gap: .35rem;
  color: var(--text-muted); font-size: 13px; font-weight: 500;
  padding: .25rem .5rem; border-radius: 6px;
  transition: color .12s, background .12s;
}
.vote-heart:hover { color: var(--brand); background: var(--bg); }
.vote-heart.voted { color: var(--brand); }
.vote-heart.voted svg { fill: var(--brand); }
.comment-count {
  display: inline-flex; align-items: center; gap: .35rem;
  color: var(--text-muted); font-size: 13px; font-weight: 500;
}
.comment-count svg { width: 14px; height: 14px; }

/* ---- Errors / notices ---- */
.error {
  color: #991b1b; background: #fef2f2; border: 1px solid #fecaca;
  padding: .65rem .9rem; border-radius: 6px; margin: 1rem 0; font-size: 13px;
}
.notice {
  color: #075985; background: #f0f9ff; border: 1px solid #bae6fd;
  padding: .65rem .9rem; border-radius: 6px; margin: 1rem 0; font-size: 13px;
}
.empty-state {
  text-align: center; padding: 3rem 1rem; color: var(--text-muted); font-size: 14px;
}

/* ---- Footer (legal links, centered, getbookshelves.app style) ---- */
.site-footer {
  border-top: 1px solid var(--border);
  margin-top: 3rem; padding: 1.5rem 1.5rem 2rem; background: var(--surface);
  text-align: center;
}
.site-footer-inner {
  max-width: 720px; margin: 0 auto;
  font-size: 12px; color: var(--text-muted); line-height: 1.7;
}
.site-footer a { color: var(--text-muted); }
.site-footer a:hover { color: var(--text); }
.site-footer .links {
  display: inline-flex; flex-wrap: wrap; justify-content: center;
  gap: .15rem .85rem; margin-bottom: .5rem;
}
.site-footer .links .sep { color: var(--border-strong); }
.site-footer .copyright { color: var(--text-muted); }

/* ---- Utility classes (replaces inline style="..." attributes) ----
   Added when removing inline styles from templates. Each class
   corresponds to a previously-inline declaration so the visual
   result is unchanged. */

/* Spacing utilities. */
.mt-1   { margin-top: 1rem; }
.mt-125 { margin-top: 1.25rem; }
.mt-15  { margin-top: 1.5rem; }
.mt-075 { margin-top: .75rem; }
.my-1   { margin: 1rem 0; }
.text-center { text-align: center; }

/* Muted helper line used in sidebars and form hints. */
.sidebar-hint {
  color: var(--text-muted); font-size: 13px; line-height: 1.5;
}
/* "(optional)" hint next to a form label. */
.label-optional {
  color: var(--text-muted); font-weight: 400;
}

/* ---- Signed-in nav affordance (fp-76m) ---- */
/* Right-side "<name> · sign out" pair next to the Submit button.
   Avatar is a small round image; referrerpolicy=no-referrer on the
   <img> avoids leaking the page URL to Google when the user came
   via OAuth. */
.signed-in-as {
  display: inline-flex; align-items: center; gap: .375rem;
  color: var(--text); font-weight: 500;
}
.signed-in-as .avatar {
  border-radius: 50%;
  vertical-align: middle;
}
/* fp-bqan: sign-out is a POST form now, but the nav still wants
   a plain-text link look. Reset button defaults + style the form
   wrapper to drop the inline-block height that submit buttons get
   by default. */
.nav-signout-form {
  display: inline-flex;
  align-items: center;
  margin: 0;
  padding: 0;
}
.nav-signout {
  display: inline-flex;
  align-items: center;
  color: var(--text-muted) !important;
  background: none;
  border: 1px solid var(--border, #d0d7de);
  border-radius: 6px;
  padding: .25rem .625rem;
  font: inherit;
  font-size: 13px;
  line-height: 1.2;
  cursor: pointer;
  text-decoration: none;
}
.nav-signout:hover {
  color: var(--text) !important;
  background: var(--bg);
}

/* ---- Account pulldown (fp-869w) ----
   Native <details>/<summary> disclosure. The panel is absolutely
   positioned under the summary, so it doesn't push the nav layout
   when open. .account-menu-item resets <button> defaults so a form-
   wrapped sign-out looks identical to a plain <a> sibling. */
.account-menu { position: relative; display: inline-block; }
.account-menu > summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
}
.account-menu > summary::-webkit-details-marker { display: none; }
.account-menu-caret {
  transition: transform .12s ease;
  color: var(--text-muted);
}
.account-menu[open] .account-menu-caret { transform: rotate(180deg); }
.account-menu-panel {
  position: absolute;
  top: calc(100% + .375rem);
  right: 0;
  min-width: 160px;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #d0d7de);
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0,0,0,.08);
  padding: .25rem;
  z-index: 50;
}
.account-menu-form { margin: 0; padding: 0; }
.account-menu-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: .4rem .625rem;
  font: inherit;
  font-size: 13px;
  line-height: 1.3;
  color: var(--text);
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
  text-decoration: none;
}
.account-menu-item:hover { background: var(--bg); }

/* ---- /account page (fp-jru) ---- */
.account-section { margin: 1.5rem 0 2rem; }
.account-section h2 {
  font-size: 14px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-muted); font-weight: 600; margin: 0 0 .75rem;
}
.linked-list, .sessions-list { list-style: none; padding: 0; margin: 0; }
.linked-row, .session-row {
  display: flex; align-items: center; gap: .75rem;
  padding: .75rem 1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: .5rem;
  font-size: 13px;
}
.linked-provider { font-weight: 600; min-width: 70px; }
.linked-email { color: var(--text-muted); }
.linked-time, .session-last-seen {
  color: var(--text-muted); margin-left: auto; font-size: 12px;
}
.session-meta {
  display: flex; flex-direction: column; gap: .125rem; flex: 1; min-width: 0;
}
.session-ua {
  font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.session-badge {
  display: inline-block;
  font-size: 11px; padding: 1px 6px; border-radius: 4px;
  background: var(--brand); color: #fff;
  width: fit-content;
}
.session-current { border-color: var(--brand); }
.session-revoke-form { margin: 0; }

/* ---- /sign-in page (fp-2rm) ---- */
.signin-cancel {
  margin-top: 1.5rem;
  font-size: 13px;
}
.signin-cancel a {
  color: var(--text-muted);
}
.signin-cancel a:hover {
  color: var(--text);
}

/* ---- Cookie consent banner + preferences modal (fp-5vy, fp-ivm9) ---- */
/* fp-ivm9: the bottom strip uses .fp-prefs-strip* (not .cookie-banner*) so
   Brave Shields' EasyList cosmetic filter doesn't hide it. Modal classes
   below keep the cookie-* prefix — the modal IDs aren't on the filter. */
.fp-prefs-strip {
  position: fixed; bottom: 0; left: 0; right: 0;
  background: rgba(255, 255, 255, 0.97);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border-top: 1px solid var(--border);
  padding: 16px; z-index: 1000;
  box-shadow: 0 -4px 6px -1px rgba(0,0,0,.08);
}
.fp-prefs-strip-content {
  max-width: 1100px; margin: 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px;
}
.fp-prefs-strip-text p {
  margin: 0; font-size: 13px; color: var(--text); line-height: 1.5;
}
.cookie-link {
  color: var(--brand); text-decoration: underline; font-weight: 500;
}
.fp-prefs-strip-actions { display: flex; gap: 12px; flex-shrink: 0; }
.cookie-btn {
  padding: 8px 16px; border-radius: 6px;
  font-size: 13px; font-weight: 500; cursor: pointer;
  border: 1px solid; transition: all .15s ease;
  white-space: nowrap; line-height: 1.3;
}
.cookie-btn-primary {
  background: var(--brand); color: #fff; border-color: var(--brand);
}
.cookie-btn-primary:hover { filter: brightness(0.92); }
.cookie-btn-secondary {
  background: transparent; color: var(--text-muted); border-color: var(--border-strong);
}
.cookie-btn-secondary:hover { background: var(--bg); color: var(--text); }

.cookie-modal {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 2000;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.cookie-modal-content {
  background: var(--surface); border-radius: 12px;
  max-width: 500px; width: 100%; max-height: 80vh; overflow-y: auto;
  box-shadow: 0 20px 25px -5px rgba(0,0,0,.18);
}
.cookie-modal-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px 24px 12px; border-bottom: 1px solid var(--border);
}
.cookie-modal-header h3 {
  margin: 0; font-size: 16px; font-weight: 600; color: var(--text);
}
.cookie-modal-close {
  background: none; border: none; font-size: 22px; color: var(--text-muted);
  cursor: pointer; padding: 4px 8px; line-height: 1; border-radius: 4px;
}
.cookie-modal-close:hover { background: var(--bg); color: var(--text); }
.cookie-modal-body { padding: 20px 24px; }
.cookie-category { margin-bottom: 20px; }
.cookie-category:last-child { margin-bottom: 0; }
.cookie-category-header { display: flex; align-items: flex-start; gap: 16px; }
.cookie-category h4 {
  margin: 0 0 4px 0; font-size: 14px; font-weight: 600; color: var(--text);
}
.cookie-category p {
  margin: 0; font-size: 13px; color: var(--text-muted); line-height: 1.5;
}
.cookie-toggle {
  position: relative; display: inline-block;
  width: 40px; height: 22px; flex-shrink: 0; margin-top: 2px;
}
.cookie-toggle input { opacity: 0; width: 0; height: 0; }
.cookie-slider {
  position: absolute; cursor: pointer; inset: 0;
  background-color: var(--border-strong);
  transition: .2s; border-radius: 22px;
}
.cookie-slider:before {
  position: absolute; content: "";
  height: 16px; width: 16px; left: 3px; bottom: 3px;
  background-color: #fff; transition: .2s; border-radius: 50%;
}
input:checked + .cookie-slider { background-color: var(--brand); }
input:checked + .cookie-slider:before { transform: translateX(18px); }
input:disabled + .cookie-slider { opacity: 0.6; cursor: not-allowed; }
.cookie-modal-footer {
  padding: 12px 24px 20px; border-top: 1px solid var(--border);
}
.cookie-modal-footer .cookie-btn {
  width: 100%; display: flex; justify-content: center;
}

@media (max-width: 640px) {
  .fp-prefs-strip-content { flex-direction: column; align-items: stretch; gap: 12px; }
  .fp-prefs-strip-actions { justify-content: stretch; }
  .cookie-btn { flex: 1; text-align: center; }
  .cookie-modal { padding: 12px; }
  .cookie-category-header { gap: 12px; }
}

/* ---- Sign-in modal (fp-eqbg) ---- */
.signin-modal {
  width: min(420px, calc(100vw - 2rem));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.75rem 1.5rem 1.5rem;
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 10px 40px rgba(0,0,0,.18);
}
.signin-modal::backdrop {
  background: rgba(15, 15, 20, .45);
}
.signin-modal h2 {
  margin: 0 0 .25rem;
  font-size: 18px;
  font-weight: 600;
}
.signin-modal-hint {
  margin: 0 0 1rem;
  color: var(--text-muted);
  font-size: 13px;
}
.signin-modal-dismiss {
  margin: 0;
  position: absolute;
  top: .5rem;
  right: .5rem;
}
.signin-modal-close {
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--text-muted);
  font-size: 22px;
  line-height: 1;
  padding: .25rem .5rem;
  cursor: pointer;
  border-radius: 4px;
}
.signin-modal-close:hover { color: var(--text); background: var(--bg); }
.signin-modal-form { margin: 0; }
.signin-modal-form label {
  display: block;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
  margin-bottom: .25rem;
}
.signin-modal-form input[type="email"] {
  width: 100%;
  padding: .5rem .65rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 14px;
  background: var(--surface);
  color: var(--text);
}
