/* SPDX-License-Identifier: Apache-2.0 */
/* Copyright 2026 dwot */

/* CannaDB stylesheet. All values come from tokens.css; if you find
 * yourself reaching for a hex code or a raw px value here, the answer
 * is to add a token, not to inline. See docs/design-language.md.
 */

/* ─── Reset (modern-normalize, vendored, trimmed) ──────────────── */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; tab-size: 4; }
body { margin: 0; }
hr { height: 0; color: inherit; }
abbr[title] { text-decoration: underline dotted; }
b, strong { font-weight: var(--weight-semibold); }
small { font-size: 80%; }
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
sub { bottom: -0.25em; }
sup { top: -0.5em; }
table { text-indent: 0; border-color: inherit; border-collapse: collapse; }
button, input, optgroup, select, textarea { font: inherit; color: inherit; margin: 0; }
button, [type="button"], [type="reset"], [type="submit"] { cursor: pointer; -webkit-appearance: button; }
::-moz-focus-inner { border-style: none; padding: 0; }
:-moz-focusring { outline: 1px dotted ButtonText; }
legend { padding: 0; }
progress { vertical-align: baseline; }
::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; }
[type="search"] { -webkit-appearance: textfield; outline-offset: -2px; }
::-webkit-search-decoration { -webkit-appearance: none; }
::-webkit-file-upload-button { -webkit-appearance: button; font: inherit; }
summary { display: list-item; }
img, picture, video, canvas, svg { display: block; max-width: 100%; }

/* ─── Base ─────────────────────────────────────────────────────── */

body {
    font-family: var(--font-sans);
    color: var(--color-fg);
    background: var(--color-bg);
    line-height: var(--leading-normal);
    font-size: var(--text-base);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

a { color: var(--color-accent); text-decoration: none; }
a:hover { text-decoration: underline; }
a:focus-visible {
    outline: 2px solid var(--color-focus);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

button, input, select, textarea { font-family: inherit; }
button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible, [role="button"]:focus-visible {
    outline: 2px solid var(--color-focus);
    outline-offset: 2px;
}

h1, h2, h3, h4, h5, h6 {
    font-weight: var(--weight-semibold);
    line-height: var(--leading-tight);
    color: var(--color-fg-strong);
    margin: var(--space-6) 0 var(--space-3);
    letter-spacing: var(--tracking-tight);
}
h1 { font-size: var(--text-3xl); margin-top: 0; }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-xl); }
h4 { font-size: var(--text-lg); }
h5, h6 { font-size: var(--text-base); }

p { margin: var(--space-3) 0; }
ul, ol { margin: var(--space-3) 0; }

code, kbd, pre, samp { font-family: var(--font-mono); font-size: 0.92em; }
code { background: var(--color-bg-sunken); padding: 0.05em 0.3em; border-radius: var(--radius-sm); }
pre {
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius);
    overflow-x: auto;
    line-height: var(--leading-snug);
}
pre code { background: transparent; padding: 0; }

hr {
    border: 0;
    border-top: 1px solid var(--color-border);
    margin: var(--space-5) 0;
}

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

/* Skip-to-main link — visible only when focused. */
.skip-link {
    position: absolute;
    left: var(--space-2);
    top: var(--space-2);
    transform: translateY(-200%);
    background: var(--color-bg-elev);
    color: var(--color-fg);
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius);
    z-index: var(--z-modal);
    font-weight: var(--weight-medium);
}
.skip-link:focus { transform: translateY(0); }

/* ─── Site chrome ───────────────────────────────────────────── */

.site-header {
    background: var(--color-bg-elev);
    border-bottom: 1px solid var(--color-border);
    position: sticky;
    top: 0;
    z-index: var(--z-header);
}

.header-inner {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: var(--space-3) var(--space-5);
    display: flex;
    align-items: center;
    gap: var(--space-5);
    flex-wrap: wrap;
}

/* Brand wordmark slot. The nav uses the inline-SVG sticker wordmark
 * (.sticker-wordmark variants below); the legacy plain-text .brand
 * rule was removed alongside the Phase-3.7 layout.html update. */

.search-form {
    flex: 1;
    min-width: 14rem;
    max-width: 28rem;
    position: relative;
    display: flex;
    gap: var(--space-2);
}
.search-form input[type="search"] {
    flex: 1;
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius);
    font-size: var(--text-sm);
    background: var(--color-bg);
    color: var(--color-fg);
    transition: border-color var(--duration) var(--easing), box-shadow var(--duration) var(--easing);
}
.search-form input[type="search"]:focus-visible {
    border-color: var(--color-accent);
    outline: none;
    box-shadow: 0 0 0 3px var(--color-accent-soft);
}
.search-form button {
    padding: var(--space-2) var(--space-4);
    border: 1px solid var(--color-accent);
    background: var(--color-accent);
    color: var(--color-accent-fg);
    border-radius: var(--radius);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    transition: background var(--duration) var(--easing), border-color var(--duration) var(--easing);
}
.search-form button:hover { background: var(--color-accent-hover); border-color: var(--color-accent-hover); }

.search-suggestions {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: var(--space-1);
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    max-height: 22rem;
    overflow-y: auto;
    z-index: var(--z-dropdown);
}
.search-suggestions:empty { display: none; }
.search-suggestions a {
    display: block;
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--color-border);
    color: var(--color-fg);
}
.search-suggestions a:last-child { border-bottom: none; }
.search-suggestions a:hover { background: var(--color-bg-sunken); text-decoration: none; }
.search-suggestions .suggest-meta { color: var(--color-fg-faint); font-size: var(--text-xs); margin-left: var(--space-2); }

.primary-nav { display: flex; gap: var(--space-4); align-items: center; }
.primary-nav a { color: var(--color-fg-muted); font-size: var(--text-sm); font-weight: var(--weight-medium); }
.primary-nav a:hover { color: var(--color-accent); }
.primary-nav .nav-me { display: inline-flex; align-items: center; line-height: 0; }
.nav-avatar {
    display: block;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    object-fit: cover;
    background: var(--color-tag-hybrid-bg);
}
.nav-avatar-placeholder { background: var(--color-tag-hybrid-bg); }
.primary-nav .nav-me:hover .nav-avatar { box-shadow: 0 0 0 2px var(--color-accent-soft); }

/* Theme toggle ─────────────────────────────────────────────────
 * Three-state cycle: light → dark → auto. Three icon SVGs are
 * inlined together; CSS shows the one matching [data-theme-pref]
 * and hides the others. Sized to match the nav avatar so the
 * right-hand cluster stays visually balanced. The icon color
 * picks up --color-fg-muted to match the nav-link rest state and
 * lifts to --color-accent on hover/focus, parallel to .primary-nav a.
 */
.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    padding: 0;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 50%;
    color: var(--color-fg-muted);
    cursor: pointer;
    transition:
        color var(--duration) var(--easing),
        background-color var(--duration) var(--easing),
        border-color var(--duration) var(--easing);
}
.theme-toggle:hover {
    color: var(--color-accent);
    background: var(--color-bg-sunken);
}
.theme-toggle:focus-visible {
    outline: 2px solid var(--color-focus);
    outline-offset: 2px;
}
.theme-toggle-icon {
    width: 1.05rem;
    height: 1.05rem;
    display: none;
}
/* Show the icon that matches the current preference. The pref
 * attribute is written by theme-toggle.js on every cycle and on
 * page load; before JS boots the button is invisible (no icon
 * matched), which is fine — it lights up as soon as the script
 * runs without us having to commit to a fallback icon that might
 * mislead the user about the active state. */
.theme-toggle[data-theme-pref="light"] .theme-toggle-icon-light,
.theme-toggle[data-theme-pref="dark"]  .theme-toggle-icon-dark,
.theme-toggle[data-theme-pref="auto"]  .theme-toggle-icon-auto {
    display: block;
}

.site-main {
    flex: 1;
    width: 100%;
    max-width: var(--max-width);
    margin: 0 auto;
    padding: var(--space-5) var(--space-5) var(--space-8);
}

.site-footer {
    border-top: 1px solid var(--color-border);
    background: var(--color-bg-elev);
    color: var(--color-fg-muted);
    font-size: var(--text-sm);
}
.footer-inner {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: var(--space-4) var(--space-5);
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-3);
}

/* ─── Hero & rails ──────────────────────────────────────────── */

.hero { padding: var(--space-5) 0 var(--space-6); }
.hero h1 { font-size: var(--text-4xl); }
.hero .lede { font-size: var(--text-lg); max-width: var(--max-width-prose); color: var(--color-fg-muted); }

/* ─── Home hero (Phase 3.7) ────────────────────────────────────
 * Brand-loud landing hero: sticker wordmark + locked tagline +
 * locked supporting sentence + two CTAs, paired with a Sage
 * avatar on the right at desktop width. Stacks on narrow viewports.
 */
.home-hero {
    padding: var(--space-7) 0 var(--space-6);
    margin-bottom: var(--space-6);
    background: var(--color-bg-cream);
    border-radius: var(--radius-lg);
}
.home-hero-content {
    display: flex;
    align-items: center;
    gap: var(--space-6);
    padding: var(--space-5);
    flex-wrap: wrap;
}
.home-hero-copy {
    flex: 1 1 24rem;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    align-items: flex-start;
}
.home-hero-copy .sticker-wordmark { margin-bottom: var(--space-2); }
.home-hero-tagline {
    font-family: var(--font-sans);
    font-weight: var(--weight-black);
    font-size: var(--text-4xl);
    line-height: var(--leading-tight);
    color: var(--color-fg-strong);
    letter-spacing: var(--tracking-tight);
    margin: 0;
    max-width: 32rem;
}
.home-hero-lede {
    font-size: var(--text-lg);
    max-width: var(--max-width-prose);
    color: var(--color-fg-soft);
    line-height: var(--leading-snug);
    margin: 0;
}
.home-hero-actions {
    display: flex;
    gap: var(--space-3);
    flex-wrap: wrap;
    margin-top: var(--space-2);
}
.home-hero-sage {
    flex: 0 0 auto;
    width: 12rem;
    height: 12rem;
    object-fit: contain;
}
@media (max-width: 40rem) {
    .home-hero-tagline { font-size: var(--text-3xl); }
    .home-hero-sage { width: 8rem; height: 8rem; }
}

.visually-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

/* ─── Home stat tiles (Phase 3.7) ──────────────────────────────
 * Replaces the prior browse-cards row. The catalog counts get
 * sticker-treatment numerals. Each tile is a single anchor 
 * wrapping its inner stack.
 */
.home-stats { margin: var(--space-6) 0; }
.stat-tiles {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
    gap: var(--space-3);
}
.stat-tile {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-1);
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-4) var(--space-5);
    color: var(--color-fg);
    text-decoration: none;
    transition: border-color var(--duration) var(--easing), transform var(--duration) var(--easing);
    height: 100%;
}
.stat-tile:hover {
    text-decoration: none;
    border-color: var(--color-border-strong);
    transform: translateY(-1px);
}
.stat-tile-number {
    font-size: var(--text-4xl);
    line-height: 1;
    margin-bottom: var(--space-2);
}
.stat-tile-label {
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
    color: var(--color-fg-strong);
}
.stat-tile-meta {
    font-size: var(--text-sm);
    color: var(--color-fg-muted);
    margin-top: auto;
}

.home-about { margin: var(--space-7) 0 var(--space-6); padding-top: var(--space-5); border-top: 1px solid var(--color-border); }
.home-about p { max-width: var(--max-width-prose); }

.rail { margin: var(--space-6) 0; }
.rail-header { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: var(--space-3); gap: var(--space-3); }
.rail-header h2 { margin: 0; }
.rail-link { font-size: var(--text-sm); color: var(--color-fg-muted); }

.empty { color: var(--color-fg-faint); font-style: italic; }

/* ─── Buttons ───────────────────────────────────────────────── */

.btn, .btn-primary, .btn-link {
    display: inline-block;
    font-family: inherit;
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    line-height: 1.2;
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius);
    border: 1px solid var(--color-border-strong);
    background: var(--color-bg-elev);
    color: var(--color-fg);
    cursor: pointer;
    transition: background var(--duration) var(--easing), border-color var(--duration) var(--easing), color var(--duration) var(--easing);
    text-decoration: none;
}
.btn:hover { background: var(--color-bg-sunken); text-decoration: none; }

.btn.btn-primary, .btn-primary {
    background: var(--color-accent);
    border-color: var(--color-accent);
    color: var(--color-accent-fg);
}
.btn.btn-primary:hover, .btn-primary:hover {
    background: var(--color-accent-hover);
    border-color: var(--color-accent-hover);
    text-decoration: none;
}

.btn-link {
    background: transparent;
    border-color: transparent;
    color: var(--color-accent);
    padding: var(--space-2) var(--space-3);
}
.btn-link:hover { text-decoration: underline; background: transparent; }

button:disabled, .btn:disabled, [aria-disabled="true"] {
    opacity: 0.55;
    cursor: not-allowed;
}

/* ─── Cards ─────────────────────────────────────────────────── */

.card-grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
    gap: var(--space-4);
}

.card {
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-4);
    transition: border-color var(--duration) var(--easing), box-shadow var(--duration) var(--easing), transform var(--duration) var(--easing);
}
.card:hover {
    border-color: var(--color-border-strong);
    box-shadow: var(--shadow);
}
.card.community-card { background: var(--color-community-bg); }
.card-title { margin: 0 0 var(--space-1); font-size: var(--text-lg); }
.card-title a { color: var(--color-fg-strong); }
.card-title a:hover { color: var(--color-accent); }
.card-meta { display: flex; gap: var(--space-2); align-items: center; margin-bottom: var(--space-2); flex-wrap: wrap; }
.card-byline { color: var(--color-fg-muted); font-size: var(--text-sm); margin: var(--space-1) 0; }
.card-excerpt { color: var(--color-fg-muted); margin: var(--space-2) 0 0; font-size: var(--text-sm); line-height: var(--leading-snug); }

/* ─── Badges & chips ────────────────────────────────────────── */

.badge {
    display: inline-block;
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    padding: 0.1rem var(--space-2);
    border-radius: var(--radius-pill);
    border: 1px solid transparent;
    font-weight: var(--weight-semibold);
    line-height: 1.5;
}
/* Trust-tier badges consume the canonical --color-editorial-* and
 * --color-community-* tokens. Phase 5 retune: community-primary visual
 * hierarchy. The trust pills are intentionally compact and lighter
 * weight — community signals (likes, reviews, popularity) are meant to
 * dominate the card; the trust pill is a small clarity cue, not a
 * headline. ~80% of the standard .badge scale; .tag-seeded parallels
 * this size for the same reason. */
.badge-editorial,
.badge-community,
.badge-verified {
    font-size: var(--text-2xs);
    padding: 0.05rem 0.5rem;
    font-weight: var(--weight-medium);
    line-height: 1.4;
}
.badge-editorial { background: var(--color-editorial-soft); border-color: var(--color-editorial); color: var(--color-editorial); }
.badge-community { background: var(--color-community-soft); border-color: var(--color-community); color: var(--color-community); }
.badge-verified  { background: var(--color-editorial-soft); border-color: var(--color-editorial); color: var(--color-editorial); }
.badge-editor    { background: var(--color-accent-soft); border-color: var(--color-accent); color: var(--color-fg); }

.kind {
    display: inline-block;
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    padding: 0.1rem var(--space-2);
    border-radius: var(--radius-pill);
    border: 1px solid var(--color-border-strong);
    color: var(--color-fg-muted);
    font-weight: var(--weight-medium);
    line-height: 1.5;
}
.kind-cut { color: var(--color-cut-fg); border-color: var(--color-cut-border); background: var(--color-cut-bg); }

.chip-list { list-style: none; padding: 0; margin: var(--space-2) 0; display: flex; flex-wrap: wrap; gap: var(--space-2); }
.chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-3);
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-pill);
    font-size: var(--text-sm);
    color: var(--color-fg-muted);
    line-height: 1.4;
}

/* ─── Alerts ─────────────────────────────────────────────────── */

.alert {
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius);
    border: 1px solid var(--color-border-strong);
    margin: var(--space-4) 0;
}
.alert-success { background: var(--color-success-bg); border-color: var(--color-success-border); color: var(--color-success); }
.alert-warning { background: var(--color-warning-bg); border-color: var(--color-warning-border); color: var(--color-warning); }
.alert-error   { background: var(--color-danger-bg);  border-color: var(--color-danger-border);  color: var(--color-danger); }
.alert-info    { background: var(--color-info-bg);    border-color: var(--color-info-border);    color: var(--color-info); }

/* ─── Forms ─────────────────────────────────────────────────── */

.form-page { max-width: var(--max-width-form); }
.form-page h1 { margin-bottom: var(--space-5); }

form fieldset {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: var(--space-4);
    margin: var(--space-3) 0;
    background: var(--color-bg-elev);
}
form legend {
    font-weight: var(--weight-semibold);
    color: var(--color-fg-strong);
    padding: 0 var(--space-2);
    font-size: var(--text-sm);
}

form label {
    display: block;
    margin-top: var(--space-3);
    margin-bottom: var(--space-1);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    color: var(--color-fg-strong);
}
form .req { color: var(--color-danger); }

form input[type="text"],
form input[type="number"],
form input[type="email"],
form input[type="url"],
form input[type="password"],
form input[type="search"],
form select,
form textarea {
    width: 100%;
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius);
    background: var(--color-bg);
    color: var(--color-fg);
    font-size: var(--text-base);
    transition: border-color var(--duration) var(--easing), box-shadow var(--duration) var(--easing);
}
form textarea { line-height: var(--leading-snug); resize: vertical; min-height: 6rem; font-family: var(--font-sans); }
form input:focus, form select:focus, form textarea:focus {
    outline: none;
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px var(--color-accent-soft);
}

form .form-hint {
    font-size: var(--text-xs);
    color: var(--color-fg-muted);
    margin: var(--space-1) 0 var(--space-3);
}

form .radio-group { display: flex; gap: var(--space-4); margin-top: var(--space-2); }
form .radio-group label { display: inline-flex; align-items: center; gap: var(--space-2); font-weight: var(--weight-regular); margin-top: 0; }

form .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
@media (max-width: 30rem) { form .form-row { grid-template-columns: 1fr; } }

.repeating-rows .ref-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); margin-bottom: var(--space-2); }
@media (max-width: 30rem) { .repeating-rows .ref-row { grid-template-columns: 1fr; } }

.form-actions {
    display: flex;
    gap: var(--space-3);
    align-items: center;
    margin-top: var(--space-5);
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-border);
}

/* Validation message slot rendered next to a field. */
.field-error {
    display: block;
    color: var(--color-danger);
    font-size: var(--text-xs);
    margin-top: var(--space-1);
}
input[aria-invalid="true"], textarea[aria-invalid="true"], select[aria-invalid="true"] {
    border-color: var(--color-danger);
    box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-danger) 10%, transparent);
}

/* Publisher attribution byline on strain/breeder cards (issue #13).
 * Small inline link with optional avatar that points to the publisher's
 * public profile. Sits below the description excerpt so the card's
 * primary information stays dominant. */
.strain-card-publisher,
.breeder-card-publisher {
    margin: var(--space-1) 0 0;
    font-size: var(--text-xs);
    color: var(--color-fg-muted);
}
.strain-card-publisher-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    color: inherit;
    text-decoration: none;
}
.strain-card-publisher-link:hover {
    color: var(--color-fg);
    text-decoration: underline;
}
.strain-card-publisher-link:focus-visible {
    color: var(--color-fg);
    text-decoration: underline;
    /* outline ring inherited from global a:focus-visible */
}
.strain-card-publisher-avatar {
    width: 1rem;
    height: 1rem;
    border-radius: 50%;
    object-fit: cover;
}

/* Entity-detail "Published by" attribution links to the profile page
 * with the publisher's avatar + display name + handle. */
.entity-attribution-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: inherit;
    text-decoration: none;
}
.entity-attribution-link:hover {
    color: var(--color-fg);
    text-decoration: underline;
}
.entity-attribution-link:focus-visible {
    color: var(--color-fg);
    text-decoration: underline;
    /* outline ring inherited from global a:focus-visible */
}
.entity-attribution-avatar {
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    object-fit: cover;
}
.entity-attribution-name {
    font-weight: var(--weight-semibold);
}

/* Review-card author link wraps the avatar + handle in an anchor;
 * keep the link visually quiet so the card doesn't read as
 * navigation-heavy. */
.review-card-avatar-link { display: inline-block; }
.review-card-author-link { color: inherit; text-decoration: none; }
.review-card-author-link:hover { text-decoration: underline; }
.review-card-author-link:focus-visible {
    text-decoration: underline;
    /* outline ring inherited from global a:focus-visible */
}

/* Public profile page (issue #13). Mirrors /me chrome but read-only;
 * the header carries the user's avatar, displayName/handle, and
 * (if the viewer is the same DID) a back-to-dashboard CTA. */
.profile-page { display: flex; flex-direction: column; gap: var(--space-5); }
.profile-header {
    display: flex;
    gap: var(--space-4);
    align-items: flex-start;
    padding: var(--space-4);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-bg-elev);
}
.profile-avatar {
    flex-shrink: 0;
    width: 5rem;
    height: 5rem;
    border-radius: 50%;
    object-fit: cover;
    background: var(--color-tag-hybrid-bg);
}
.profile-avatar-placeholder { background: var(--color-tag-hybrid-bg); }
.profile-identity { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.profile-name { margin: 0; }
.profile-handle { margin: 0; color: var(--color-fg-muted); }
.profile-meta { margin: 0; font-size: var(--text-sm); color: var(--color-fg-muted); }
.profile-self-cta { margin-top: var(--space-2); }

/* Danger-zone block on edit pages — visually separated from the main
 * form so a Delete click isn't a misclick away from Save. */
.danger-zone {
    margin-top: var(--space-6);
    padding: var(--space-4);
    border: 1px solid var(--color-danger-border);
    border-radius: var(--radius-lg);
    background: var(--color-danger-bg);
}
.danger-zone-title {
    color: var(--color-danger);
    margin: 0 0 var(--space-2);
}
.btn-danger {
    background: var(--color-danger);
    color: var(--color-on-danger);
    border: 1px solid var(--color-danger);
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-md);
    cursor: pointer;
}
.btn-danger:hover, .btn-danger:focus-visible {
    filter: brightness(1.1);
    outline: none;
}

.checkbox-label { display: inline-flex; align-items: center; gap: var(--space-2); margin-top: var(--space-3); font-weight: var(--weight-regular) !important; }

/* ─── Form section (styled details replacing bare <details>) ── */

.form-section {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    margin: var(--space-4) 0;
    background: var(--color-bg-elev);
    padding: 0;
}
details.form-section[open] { padding-bottom: var(--space-4); }
.form-section > summary {
    list-style: none;
    cursor: pointer;
    padding: var(--space-3) var(--space-4);
    font-weight: var(--weight-semibold);
    color: var(--color-fg-strong);
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-radius: var(--radius-md);
    user-select: none;
}
.form-section > summary::-webkit-details-marker { display: none; }
.form-section > summary::after {
    content: "+";
    color: var(--color-fg-muted);
    font-size: var(--text-xl);
    line-height: 1;
    transition: transform var(--duration) var(--easing);
}
details.form-section[open] > summary::after { content: "−"; }
.form-section > summary:hover { background: var(--color-bg-sunken); }
fieldset.form-section { padding: var(--space-3) var(--space-4) var(--space-4); }
fieldset.form-section > legend { padding: 0 var(--space-2); }
.form-section > *:not(summary):not(legend) { padding-left: var(--space-4); padding-right: var(--space-4); }
fieldset.form-section > *:not(summary):not(legend) { padding-left: 0; padding-right: 0; }

/* ─── Markdown editor (write/preview tabs) ──────────────────── */

.md-editor {
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius);
    background: var(--color-bg-elev);
    overflow: hidden;
    margin-top: var(--space-1);
}
.md-tabs {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-2);
    background: var(--color-bg-sunken);
    border-bottom: 1px solid var(--color-border);
}
.md-tab {
    background: transparent;
    border: 1px solid transparent;
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius);
    font-size: var(--text-sm);
    color: var(--color-fg-muted);
    font-weight: var(--weight-medium);
    cursor: pointer;
    transition: background var(--duration) var(--easing), color var(--duration) var(--easing), border-color var(--duration) var(--easing);
}
.md-tab:hover { background: var(--color-bg-elev); color: var(--color-fg); }
.md-tab.is-active {
    background: var(--color-bg-elev);
    border-color: var(--color-border-strong);
    color: var(--color-fg-strong);
}
.md-hint {
    margin-left: auto;
    color: var(--color-fg-faint);
    font-size: var(--text-xs);
}
.md-pane { display: none; }
.md-pane.is-active { display: block; }
.md-pane-write textarea {
    border: 0;
    width: 100%;
    padding: var(--space-3) var(--space-4);
    background: transparent;
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
    resize: vertical;
}
/* Textarea inherits the global textarea:focus-visible ring (a 2px
 * focus-color outline at +2px offset). The earlier `outline: none;
 * box-shadow: none;` here removed both signals with nothing replacing
 * them, leaving keyboard users without a focus indicator. */
.md-pane-preview { padding: var(--space-3) var(--space-4); min-height: 8rem; }
.md-pane-preview .empty { margin: 0; }
.htmx-request.md-tab[data-md-tab="preview"] { opacity: 0.6; }

/* ─── Typeahead + ref-row chips ─────────────────────────────── */

.ref-row {
    display: grid;
    grid-template-columns: 1fr auto auto;
    gap: var(--space-2);
    align-items: center;
    margin-bottom: var(--space-2);
}
.ref-row .typeahead { position: relative; }
.ref-row .typeahead input { width: 100%; }

.typeahead-results {
    position: absolute;
    top: calc(100% + var(--space-1));
    left: 0;
    right: 0;
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    max-height: 18rem;
    overflow-y: auto;
    z-index: var(--z-dropdown);
}
.typeahead-results:empty { display: none; }
.typeahead-list {
    list-style: none;
    margin: 0;
    padding: var(--space-1);
}
.typeahead-list li { margin: 0; }
.typeahead-result {
    display: flex;
    flex-direction: column;
    gap: 2px;
    width: 100%;
    text-align: left;
    background: transparent;
    border: 1px solid transparent;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    cursor: pointer;
    color: var(--color-fg);
}
.typeahead-result:hover, .typeahead-result.is-active {
    background: var(--color-accent-soft);
    border-color: var(--color-accent);
}
.typeahead-result .typeahead-name { font-weight: var(--weight-medium); }
.typeahead-result .typeahead-meta { font-size: var(--text-xs); color: var(--color-fg-muted); }
.typeahead-empty {
    padding: var(--space-2) var(--space-3);
    margin: 0;
    color: var(--color-fg-muted);
    font-size: var(--text-sm);
    font-style: italic;
}
.typeahead-indicator { display: none; }
.htmx-request .typeahead-indicator {
    display: inline-block;
    position: absolute;
    right: var(--space-3);
    top: 50%;
    width: 0.75rem;
    height: 0.75rem;
    margin-top: -0.4rem;
    border: 2px solid var(--color-border-strong);
    border-top-color: var(--color-accent);
    border-radius: 50%;
    animation: ref-spin 0.7s linear infinite;
}
@keyframes ref-spin { to { transform: rotate(360deg); } }

.ref-state-chip {
    display: none;
    align-items: center;
    gap: var(--space-1);
    font-size: var(--text-xs);
    padding: 0.1rem var(--space-2);
    border-radius: var(--radius-pill);
    border: 1px solid transparent;
    line-height: 1.5;
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    font-weight: var(--weight-medium);
}
.ref-row.is-linked .ref-linked-chip {
    display: inline-flex;
    background: var(--color-editorial-bg);
    border-color: var(--color-editorial-border);
    color: var(--color-editorial-fg);
}
.ref-row.is-fallback .ref-fallback-chip {
    display: inline-flex;
    background: var(--color-community-bg);
    border-color: var(--color-community-border);
    color: var(--color-community-fg);
}
.ref-dot {
    display: inline-block;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: currentColor;
}
.ref-clear {
    background: transparent;
    border: 0;
    color: var(--color-fg-faint);
    font-size: var(--text-lg);
    cursor: pointer;
    padding: 0 var(--space-2);
    line-height: 1;
}
.ref-clear:hover { color: var(--color-danger); }
.ref-row:not(.is-linked):not(.is-fallback) .ref-clear { visibility: hidden; }

@media (max-width: 30rem) {
    .ref-row { grid-template-columns: 1fr auto; }
    .ref-row .ref-state-chip { grid-column: 1; }
}

/* The breeder social-links rows reuse the ref-row layout but don't
 * have typeahead — give them a simpler two-input shape. */
.ref-row.social-row { grid-template-columns: 1fr 2fr; }

/* ─── Strain form: lineage rows with parent-breeder column ────
 * The parent ref-row plus an optional "breeder of this parent"
 * input. Stacks below 30rem so the breeder field doesn't squeeze
 * the typeahead. */
.lineage-rows .lineage-row {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    gap: var(--space-2);
    align-items: start;
    margin-bottom: var(--space-3);
}
.lineage-rows .lineage-row .ref-row { margin-bottom: 0; }
.lineage-rows .parent-breeder-input { margin-top: 0; }
@media (max-width: 30rem) {
    .lineage-rows .lineage-row { grid-template-columns: 1fr; }
}

/* ─── Strain form: range input groups ─────────────────────────
 * Paired min/max number inputs with a separator. The yield
 * variant adds a unit dropdown after the max input. Stacks on
 * narrow viewports so the inputs stay readable on 380px. */
.range-fieldset {
    border: 0;
    padding: 0;
    margin: var(--space-3) 0 var(--space-2);
}
.range-fieldset > legend.range-legend {
    padding: 0;
    margin: 0 0 var(--space-1);
    font-weight: var(--weight-medium);
    color: var(--color-fg);
    font-size: var(--text-sm);
}
.range-input-group {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    gap: var(--space-2);
    align-items: end;
}
.range-input-group-with-unit {
    grid-template-columns: 1fr auto 1fr auto;
}
.range-input { display: flex; flex-direction: column; }
.range-input > label {
    margin: 0 0 var(--space-1);
    font-size: var(--text-xs);
    color: var(--color-fg-muted);
    font-weight: var(--weight-regular);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
}
.range-input > input,
.range-input > select { margin-top: 0; }
.range-sep {
    align-self: center;
    color: var(--color-fg-faint);
    padding-bottom: var(--space-2);
    user-select: none;
}
.range-unit { min-width: 9rem; }
@media (max-width: 30rem) {
    .range-input-group,
    .range-input-group-with-unit {
        grid-template-columns: 1fr;
    }
    .range-sep { display: none; }
}

/* ─── Strain form: seed-availability checkbox grid ────────────
 * Multi-checkbox group: two-column grid on wide viewports,
 * single column on narrow. Reuses .checkbox-label styling. */
.checkbox-grid {
    border: 0;
    padding: 0;
    margin: var(--space-3) 0 var(--space-2);
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-1) var(--space-3);
}
.checkbox-grid > legend {
    grid-column: 1 / -1;
    padding: 0;
    margin: 0 0 var(--space-1);
    font-weight: var(--weight-medium);
    color: var(--color-fg);
    font-size: var(--text-sm);
}
.checkbox-grid > .form-hint { grid-column: 1 / -1; margin-top: 0; }
.checkbox-grid > .checkbox-label { margin-top: 0; }
.checkbox-grid > .field-error { grid-column: 1 / -1; }
@media (max-width: 30rem) {
    .checkbox-grid { grid-template-columns: 1fr; }
}

/* ─── Strain form: tag-input suggestion chips ─────────────────
 * Small clickable chips beneath each open-vocab tag input. Click
 * to add/remove the suggestion from the comma-separated value.
 * Toggled state mirrors aria-pressed. */
.tag-suggestions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    margin: var(--space-1) 0 var(--space-2);
}
.tag-suggestions:empty { display: none; }
.tag-suggestion-chip {
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border-strong);
    color: var(--color-fg-muted);
    padding: 0.1rem var(--space-2);
    font-size: var(--text-xs);
    border-radius: var(--radius-pill);
    cursor: pointer;
    line-height: 1.5;
    transition: background var(--duration) var(--easing), color var(--duration) var(--easing), border-color var(--duration) var(--easing);
}
.tag-suggestion-chip:hover { background: var(--color-accent-soft); color: var(--color-fg); }
.tag-suggestion-chip.is-selected {
    background: var(--color-accent-soft);
    border-color: var(--color-accent);
    color: var(--color-fg-strong);
    font-weight: var(--weight-medium);
}

/* ─── Draft recovery toast ─────────────────────────────────── */

.draft-toast {
    background: var(--color-info-bg);
    border: 1px solid var(--color-info-border);
    border-radius: var(--radius);
    padding: var(--space-3) var(--space-4);
    margin-bottom: var(--space-4);
    color: var(--color-info);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
}
.draft-toast .btn { margin-left: auto; }

/* ─── Entity pages (strain + breeder shared chrome) ─────────── */

.strain-page, .breeder-page { max-width: 56rem; }

.entity-header {
    border-bottom: 1px solid var(--color-border);
    padding-bottom: var(--space-4);
    margin-bottom: var(--space-5);
}
.entity-header h1 { font-size: var(--text-4xl); margin-bottom: var(--space-2); }
.entity-subtitle {
    color: var(--color-fg-muted);
    margin: 0;
    display: flex;
    gap: var(--space-2);
    align-items: center;
    flex-wrap: wrap;
    font-size: var(--text-sm);
}
.entity-subtitle .meta { color: var(--color-fg-muted); }
.entity-subtitle .also-known-as { display: inline-flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; color: var(--color-fg-muted); }
.entity-subtitle .aka-chip { color: var(--color-fg); font-style: italic; }
.entity-subtitle .aka-sep { color: var(--color-fg-faint); }

.entity-attribution {
    margin-top: var(--space-3);
    display: flex;
    gap: var(--space-2);
    align-items: center;
    flex-wrap: wrap;
    font-size: var(--text-sm);
}
.entity-attribution .attribution-label { color: var(--color-fg-faint); text-transform: uppercase; letter-spacing: var(--tracking-wide); font-size: var(--text-xs); }
.entity-attribution .handle { font-size: var(--text-sm); color: var(--color-fg-strong); background: var(--color-bg-elev); border: 1px solid var(--color-border); }
.entity-attribution .did { font-size: var(--text-xs); color: var(--color-fg-muted); }

.record-actions { margin: var(--space-3) 0 0; display: flex; gap: var(--space-2); }

/* Quick facts strip — between header and body. */
.quick-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: var(--space-3) var(--space-5);
    margin: 0 0 var(--space-5);
    padding: var(--space-4);
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}
.quick-facts .fact dt {
    font-size: var(--text-xs);
    color: var(--color-fg-faint);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    margin-bottom: var(--space-1);
}
.quick-facts .fact dd { margin: 0; font-size: var(--text-base); color: var(--color-fg-strong); font-weight: var(--weight-medium); }

.fact-lean { grid-column: 1 / -1; }
.lean-text { display: block; font-size: var(--text-sm); color: var(--color-fg); margin-bottom: var(--space-1); font-weight: var(--weight-medium); }
.lean-bar { display: block; }
.lean-bar-track {
    position: relative;
    display: block;
    height: 6px;
    background: linear-gradient(to right, var(--color-cut-fg) 0%, var(--color-bg-sunken) 50%, var(--color-accent) 100%);
    border-radius: var(--radius-pill);
    overflow: visible;
}
.lean-bar-marker {
    position: absolute;
    top: -4px;
    width: 14px;
    height: 14px;
    margin-left: -7px;
    border-radius: 50%;
    background: var(--color-bg-elev);
    border: 2px solid var(--color-fg-strong);
    box-shadow: var(--shadow-sm);
}
.lean-bar-labels { display: flex; justify-content: space-between; font-size: var(--text-xs); color: var(--color-fg-faint); margin-top: var(--space-1); text-transform: uppercase; letter-spacing: var(--tracking-wide); }

/* Body / sections */
.entity-body { margin: var(--space-5) 0; }
.entity-relations { margin: var(--space-5) 0; display: grid; gap: var(--space-5); grid-template-columns: 1fr 1fr; }
@media (max-width: 50rem) { .entity-relations { grid-template-columns: 1fr; } }
.relation-block h2 { margin-top: 0; font-size: var(--text-lg); }
.relation-summary { margin: var(--space-2) 0; display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.relation-summary .relation-label { font-size: var(--text-xs); color: var(--color-fg-faint); text-transform: uppercase; letter-spacing: var(--tracking-wide); margin-right: var(--space-1); }
.relation-summary .rel-sep { color: var(--color-fg-faint); }
.relation-more { font-size: var(--text-sm); color: var(--color-fg-muted); }

.rel-chip {
    display: inline-block;
    padding: var(--space-1) var(--space-3);
    background: var(--color-accent-soft);
    color: var(--color-accent-hover);
    border-radius: var(--radius-pill);
    font-size: var(--text-sm);
    border: 1px solid transparent;
    font-weight: var(--weight-medium);
}
.rel-chip:hover { text-decoration: none; background: var(--color-accent); color: var(--color-accent-fg); }
.rel-chip.rel-fallback {
    background: var(--color-bg-sunken);
    color: var(--color-fg-muted);
    border-color: var(--color-border-strong);
    font-style: italic;
}

.entity-claims { margin: var(--space-6) 0; }
.entity-claims > h2 { border-bottom: 1px solid var(--color-border); padding-bottom: var(--space-2); }
.claims-block { margin: var(--space-4) 0; }
.claims-block h3 { font-size: var(--text-base); color: var(--color-fg-faint); text-transform: uppercase; letter-spacing: var(--tracking-wide); margin-bottom: var(--space-2); margin-top: var(--space-4); }

.entity-duplicates, .entity-strains, .entity-links { margin: var(--space-6) 0; }

.fact-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    gap: var(--space-3) var(--space-5);
    margin: var(--space-4) 0;
    padding: var(--space-4);
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}
.fact dt { font-size: var(--text-xs); color: var(--color-fg-faint); text-transform: uppercase; letter-spacing: var(--tracking-wide); margin-bottom: var(--space-1); }
.fact dd { margin: 0; font-size: var(--text-base); color: var(--color-fg); }

.markdown { line-height: var(--leading-prose); max-width: var(--max-width-prose); }
.markdown p { margin: var(--space-3) 0; }
.markdown ul, .markdown ol { padding-left: var(--space-5); }
.markdown a { word-break: break-word; }
.markdown blockquote {
    margin: var(--space-4) 0;
    padding: var(--space-2) var(--space-4);
    border-left: 3px solid var(--color-border-strong);
    color: var(--color-fg-muted);
    font-style: italic;
}
.markdown h2, .markdown h3 { margin-top: var(--space-5); }

.relation-list { list-style: none; padding: 0; margin: var(--space-2) 0; }
.relation-list li { padding: var(--space-2) 0; border-bottom: 1px solid var(--color-border); }
.relation-list li:last-child { border-bottom: none; }
.relation-list .name-fallback { color: var(--color-fg-muted); }

details.raw-record { margin-top: var(--space-6); }
details.raw-record summary { cursor: pointer; color: var(--color-fg-muted); font-size: var(--text-sm); }
details.raw-record pre { margin-top: var(--space-2); }

/* ─── Lineage + versions pages ─────────────────────────────── */

.lineage-page, .versions-page { max-width: 64rem; }
.lineage-header { margin-bottom: var(--space-5); }
.lineage-header h1 { margin: var(--space-2) 0 var(--space-2); }
.lineage-back { font-size: var(--text-sm); margin: 0; }

.lineage-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    color: var(--color-fg-muted);
    font-size: var(--text-sm);
    margin: var(--space-2) 0;
}
.legend-item { display: inline-flex; align-items: center; gap: var(--space-2); }
.legend-swatch {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    border-radius: var(--radius-sm);
    background: var(--color-bg-elev);
}
.legend-editorial { border: 2px solid var(--color-editorial-border); }
.legend-community { border: 1.5px dashed var(--color-community-border); }
.legend-cut { border: 1.5px solid var(--color-cut-accent); transform: rotate(45deg); width: 0.85rem; height: 0.85rem; }

.lineage-page .lineage-cols {
    display: grid;
    grid-template-columns: 20rem 1fr;
    gap: var(--space-6);
}
@media (max-width: 60rem) {
    .lineage-page .lineage-cols { grid-template-columns: 1fr; }
}

.lineage-tree {
    list-style: none;
    padding-left: 0;
    margin: 0;
}
.lineage-tree ul {
    list-style: none;
    padding-left: var(--space-5);
    margin: var(--space-1) 0 0;
    border-left: 1px solid var(--color-border);
    margin-left: var(--space-2);
}
.lineage-tree li { padding: var(--space-1) 0; position: relative; font-size: var(--text-sm); }
.lineage-tree > li > .lineage-link, .lineage-tree > li > .lineage-fallback { font-weight: var(--weight-semibold); font-size: var(--text-base); }
.lineage-tree ul li::before {
    content: "";
    position: absolute;
    left: calc(-1 * var(--space-5));
    top: 0.85em;
    width: var(--space-4);
    height: 1px;
    background: var(--color-border);
}
.lineage-link { color: var(--color-accent); }
.lineage-fallback { color: var(--color-fg-muted); font-style: italic; cursor: help; border-bottom: 1px dotted var(--color-fg-faint); }

.cyto-wrap { position: relative; }
#cyto {
    width: 100%;
    height: 32rem;
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}
@media (max-width: 40rem) { #cyto { height: 24rem; } }

.cyto-controls {
    position: absolute;
    top: var(--space-3);
    right: var(--space-3);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: var(--space-1);
    box-shadow: var(--shadow-sm);
}
.cyto-btn {
    background: transparent;
    border: 0;
    width: 2rem;
    height: 2rem;
    font-size: var(--text-base);
    color: var(--color-fg);
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.cyto-btn:hover { background: var(--color-bg-sunken); }

.cyto-tooltip {
    position: absolute;
    background: var(--color-fg-strong);
    color: var(--color-bg);
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
    font-size: var(--text-xs);
    pointer-events: none;
    z-index: var(--z-dropdown);
    box-shadow: var(--shadow);
    max-width: 14rem;
}
.cyto-tooltip strong { display: block; }
/* Inherit color from the parent tooltip (which sets the on-surface fg)
 * and dim with opacity so the rule reads correctly in both light and
 * dark — the prior explicit color baked the light-mode parchment in. */
.cyto-tooltip-meta { display: block; margin-top: var(--space-1); text-transform: uppercase; letter-spacing: var(--tracking-wide); font-size: var(--text-2xs); opacity: 0.75; }

.lineage-list-disclosure { margin-top: var(--space-4); }
.lineage-list-disclosure > summary { cursor: pointer; color: var(--color-fg-muted); font-size: var(--text-sm); }
.descendant-list { list-style: none; padding: 0; margin: var(--space-2) 0; }
.descendant-list li { padding: var(--space-1) 0; border-bottom: 1px solid var(--color-border); display: flex; justify-content: space-between; gap: var(--space-3); align-items: baseline; }
.descendant-list li:last-child { border-bottom: none; }
.descendant-depth { font-size: var(--text-xs); color: var(--color-fg-faint); text-transform: uppercase; letter-spacing: var(--tracking-wide); }

.versions-block { margin: var(--space-6) 0; }
.versions-direction { color: var(--color-fg-muted); font-weight: var(--weight-semibold); font-size: var(--text-lg); }
.versions-block h2 { font-size: var(--text-lg); margin-bottom: var(--space-3); }

/* ─── Lists / search ────────────────────────────────────────── */

.list-page .list-header {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    border-bottom: 1px solid var(--color-border);
    padding-bottom: var(--space-3);
    margin-bottom: var(--space-4);
}
.list-page .list-header h1 { margin: 0; }
.list-summary { color: var(--color-fg-muted); font-size: var(--text-sm); margin: 0; }

.list-filters {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    align-items: center;
    margin: 0 0 var(--space-5);
    padding: var(--space-3) var(--space-4);
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}
.list-filters .filter { display: flex; align-items: center; gap: var(--space-2); margin: 0; padding: 0; border: 0; }
.list-filters .filter-label { font-size: var(--text-xs); color: var(--color-fg-faint); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
.list-filters select { padding: var(--space-1) var(--space-2); border: 1px solid var(--color-border-strong); border-radius: var(--radius); background: var(--color-bg); }
.list-filters .filter-kind { display: flex; align-items: center; gap: var(--space-2); }
.kind-option {
    padding: var(--space-1) var(--space-3);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    cursor: pointer;
    font-size: var(--text-sm);
    color: var(--color-fg-muted);
    background: var(--color-bg);
}
.kind-option input { display: none; }
.kind-option.is-active {
    background: var(--color-accent);
    color: var(--color-accent-fg);
    border-color: var(--color-accent);
}

.list-page .pagination,
.search-page .pagination { margin-top: var(--space-5); display: flex; gap: var(--space-3); }

.search-results { list-style: none; padding: 0; margin: 0; }
.search-empty { padding: var(--space-5) 0; }
.search-empty .empty { font-size: var(--text-base); margin-bottom: var(--space-3); }

.error-page { text-align: center; padding: var(--space-7) var(--space-4); }
.error-page h1 { font-size: var(--text-2xl); }

/* ─── Editor surfaces ───────────────────────────────────────── */

.stat-grid {
    list-style: none;
    padding: 0;
    margin: var(--space-4) 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    gap: var(--space-3);
}
.stat-grid li {
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: var(--space-3) var(--space-4);
    color: var(--color-fg-muted);
    font-size: var(--text-sm);
}
.stat-grid li strong {
    display: block;
    color: var(--color-fg-strong);
    font-size: var(--text-2xl);
    font-weight: var(--weight-semibold);
    line-height: 1;
    margin-bottom: var(--space-1);
}

.editor-nav { display: flex; gap: var(--space-3); flex-wrap: wrap; margin: var(--space-4) 0; }

.cluster-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--space-4); }
.cluster-card {
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-4);
}
.cluster-header {
    display: flex;
    gap: var(--space-3);
    align-items: baseline;
    margin-bottom: var(--space-3);
    color: var(--color-fg-muted);
    font-size: var(--text-sm);
    padding-bottom: var(--space-3);
    border-bottom: 1px solid var(--color-border);
}
.cluster-header .similarity { font-weight: var(--weight-semibold); color: var(--color-fg-strong); font-size: var(--text-base); }
.cluster-header .reason { font-style: italic; }
.cluster-records {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3);
    border: 0;
    padding: 0;
    background: transparent;
    margin: 0 0 var(--space-4);
}
@media (max-width: 40rem) { .cluster-records { grid-template-columns: 1fr; } }
.cluster-record {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-3);
    border: 1.5px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-bg);
    cursor: pointer;
    transition: border-color var(--duration) var(--easing), background var(--duration) var(--easing);
}
.cluster-record:hover { border-color: var(--color-border-strong); }
.cluster-record:has(input:checked) { border-color: var(--color-accent); background: var(--color-accent-soft); }
.cluster-record.is-editorial {
    border-color: var(--color-editorial-border);
    background: var(--color-editorial-bg);
}
.cluster-record-body { display: flex; flex-direction: column; gap: var(--space-1); flex: 1; }
.cluster-record-name a { color: var(--color-fg-strong); font-weight: var(--weight-semibold); }
.cluster-record-tier {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--color-fg-faint);
}
.cluster-record-did { color: var(--color-fg-faint); font-family: var(--font-mono); font-size: var(--text-xs); word-break: break-all; }

.rationale-block { margin: var(--space-3) 0; }
.rationale-block label { display: block; font-size: var(--text-xs); color: var(--color-fg-faint); text-transform: uppercase; letter-spacing: var(--tracking-wide); margin-bottom: var(--space-1); font-weight: var(--weight-medium); }
.rationale-block textarea { width: 100%; padding: var(--space-2) var(--space-3); border: 1px solid var(--color-border-strong); border-radius: var(--radius); background: var(--color-bg); }
.cluster-actions { padding-top: 0; border-top: 0; margin-top: 0; }

.editor-header { margin-bottom: var(--space-5); }
.editor-header h1 { margin-bottom: var(--space-1); }
.editor-rails { display: grid; gap: var(--space-6); margin-top: var(--space-5); }

.decisions-list { list-style: none; padding: 0; margin: 0; }
.decision-row {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-1) var(--space-3);
    padding: var(--space-2) 0;
    border-bottom: 1px solid var(--color-border);
    font-size: var(--text-sm);
    align-items: baseline;
}
.decision-row:last-child { border-bottom: none; }
.decision-when { font-size: var(--text-xs); color: var(--color-fg-faint); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
.decision-arrow { display: inline-flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }
.decision-rationale { grid-column: 2; color: var(--color-fg-muted); font-style: italic; }

.canon-uri { font-family: var(--font-mono); font-size: var(--text-xs); word-break: break-all; }
.canon-when { white-space: nowrap; color: var(--color-fg-muted); }
.canon-editor { font-size: var(--text-xs); color: var(--color-fg-muted); }
.list-filters .filter-grow { flex: 1; min-width: 14rem; }
.list-filters input[type="search"], .list-filters input[type="text"] {
    padding: var(--space-1) var(--space-2);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius);
    background: var(--color-bg);
    min-width: 12rem;
    font-size: var(--text-sm);
}

.canon-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
}
.canon-table th, .canon-table td {
    text-align: left;
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--color-border);
    vertical-align: top;
}
.canon-table th { color: var(--color-fg-muted); font-weight: var(--weight-semibold); background: var(--color-bg-sunken); }

/* ─── Auth / me ─────────────────────────────────────────────── */

.auth-page { max-width: var(--max-width-form); }
.auth-form { margin-top: var(--space-4); }
.auth-form label { display: block; margin-bottom: var(--space-1); }
.auth-form input { width: 100%; padding: var(--space-2) var(--space-3); border: 1px solid var(--color-border-strong); border-radius: var(--radius); background: var(--color-bg); }
.auth-form input:focus { outline: none; border-color: var(--color-accent); box-shadow: 0 0 0 3px var(--color-accent-soft); }
.auth-form button { margin-top: var(--space-3); }
.auth-help { color: var(--color-fg-muted); font-size: var(--text-sm); margin-top: var(--space-4); }

.me-page .me-header {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid var(--color-border);
    padding-bottom: var(--space-3);
    margin-bottom: var(--space-4);
}
.me-page .me-meta { color: var(--color-fg-muted); font-size: var(--text-sm); display: flex; gap: var(--space-3); align-items: center; flex-wrap: wrap; margin: 0; }
.me-page .me-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-bottom: var(--space-5); }
.logout-form { margin: 0; }
.logout-form button {
    background: transparent;
    border: 1px solid var(--color-border-strong);
    padding: var(--space-1) var(--space-3);
    font-size: var(--text-sm);
    border-radius: var(--radius);
    color: var(--color-fg-muted);
}
.logout-form button:hover { border-color: var(--color-danger); color: var(--color-danger); }

/* ──────────────────────────────────────────────────────────────
 * Phase 3.7 component foundation
 *
 * The classes below land the brand vocabulary defined in
 * cannadb/docs/brand-identity.md: sticker treatment, the Sage
 * avatar system, the Sage's-Note callout, tag pills, the
 * connected-box lineage tree, the effects-bar chart, the
 * review-card layout, the related-strains rail, and the empty
 * state. Per-template usage lands in Phases 2–6; this section
 * is pure component foundation.
 * ────────────────────────────────────────────────────────────── */

/* ─── Section header type scale ────────────────────────────────
 * Originally a Bagel Fat One sticker treatment (yellow fill +
 * heavy ink outline) shared with the SVG wordmark. The bubble
 * face read poorly at body-header scale and pinched the
 * accessible-contrast budget once the dark theme landed, so the
 * .sticker class is now a plain Inter-bold heading style — the
 * sticker visual is reserved for the wordmark/logo only (see
 * .sticker-wordmark below). The class name is kept so the
 * existing template markup (sticker-h1/h2/h3 size variants) keeps
 * working without a sweep through every page.
 */
.sticker {
    font-family: var(--font-sans);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-tight);
    line-height: var(--leading-tight);
    color: var(--color-fg-strong);
}
.sticker-h1 { font-size: var(--text-4xl); }
.sticker-h2 { font-size: var(--text-2xl); }
.sticker-h3 { font-size: var(--text-xl); }

/* ─── Sticker wordmark (nav + landing hero) ────────────────────
 * Wraps an inline SVG <text> wordmark — see layout.html for the
 * one-of-one nav instance and home.html for the hero instance.
 * Sizing happens via the wrapper height; the SVG scales to fit.
 */
.sticker-wordmark {
    display: inline-flex;
    align-items: center;
    text-decoration: none;
    line-height: 0;
}
.sticker-wordmark svg { display: block; height: 100%; width: auto; }
.sticker-wordmark:hover { text-decoration: none; }
/* Drive the SVG <text> fill + stroke from tokens so the wordmark
 * tracks the active theme. The SVG markup carries fill="none" on
 * the outline-only back text and fill="#FFD56B" on the front text;
 * we override stroke universally and only swap fill on the front
 * (non-"none") text, leaving the back-stroke text fill: none so
 * the outline stays an outline. */
.sticker-wordmark svg text { stroke: var(--color-wordmark-stroke); }
.sticker-wordmark svg text:not([fill="none"]) { fill: var(--color-wordmark-fill); }
.sticker-wordmark-nav  { height: 2.75rem; }   /* ~44px — sized so the nav wordmark
                                                   is a true proportional miniature of
                                                   the home hero (same 17% stroke ratio)
                                                   rather than a thinner variant. Below
                                                   ~40px the bubble outline starts to
                                                   sub-pixel-render fuzzily regardless
                                                   of stroke ratio. */
.sticker-wordmark-hero { height: 4.5rem; }    /* ~--text-5xl scale */
@media (max-width: 30rem) {
    .sticker-wordmark-hero { height: 3rem; }
}

/* ─── Sage avatars ──────────────────────────────────────────────
 * A circular frame around an <img> pointing at one of the five
 * expression SVGs in /static/img/sage/. The expression modifier
 * classes (.sage-aha etc.) are documentation hooks — the actual
 * src is set in markup. Default size = 44px (.sage-avatar-md).
 */
.sage-avatar {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: 2.75rem;       /* 44px default */
    height: 2.75rem;
    border-radius: 50%;
    overflow: hidden;
    background: var(--color-bg-cream);
}
.sage-avatar img,
.sage-avatar svg {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.sage-avatar-sm { width: 2rem;    height: 2rem; }     /* 32px */
.sage-avatar-md { width: 2.75rem; height: 2.75rem; }  /* 44px */
.sage-avatar-lg { width: 5.5rem;  height: 5.5rem; }   /* 88px */

/* Optional: hover micro-motion on Sage. Subtle scale only;
 * frozen under prefers-reduced-motion (tokens reset duration). */
.sage-avatar { transition: transform var(--duration) var(--easing); }
.sage-avatar:hover { transform: scale(1.04); }

/* ─── Sage's Note callout ──────────────────────────────────────
 * Lavender card embedding strain-specific commentary. The
 * eyebrow ("SAGE'S NOTE") sits above the body, both in Inter.
 */
.sage-note {
    display: flex;
    gap: var(--space-3);
    align-items: flex-start;
    background: var(--color-bg-lavender);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
    margin: var(--space-4) 0;
}
.sage-note .sage-avatar { background: var(--color-bg-elev); }
.sage-note-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    flex: 1;
    min-width: 0;
}
.sage-note-eyebrow {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--color-fg-muted);
    font-weight: var(--weight-semibold);
    line-height: 1;
    margin: 0;
}
.sage-note-text {
    font-size: var(--text-sm);
    color: var(--color-fg);
    line-height: var(--leading-snug);
    margin: 0;
}

/* ─── Tag pills ────────────────────────────────────────────────
 * Cannabis-domain metadata pills: hybrid (green), indica
 * (purple), sativa/thc (amber), Sage's Pick (pink). Always
 * paired with text — color is never the sole signal.
 */
.tag {
    display: inline-flex;
    align-items: center;
    padding: 0.15rem var(--space-3);
    border-radius: var(--radius-pill);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    line-height: 1.5;
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    border: 1px solid transparent;
}
.tag-hybrid { background: var(--color-tag-hybrid-bg); color: var(--color-tag-hybrid-fg); }
.tag-indica { background: var(--color-tag-indica-bg); color: var(--color-tag-indica-fg); }
.tag-sativa { background: var(--color-tag-sativa-bg); color: var(--color-tag-sativa-fg); }
.tag-thc    { background: var(--color-tag-thc-bg);    color: var(--color-tag-thc-fg); }
.tag-pick   { background: var(--color-tag-pick-bg);   color: var(--color-tag-pick-fg); }
/* Phase 5 community-primary retune: editorial-seeded records get a
 * compact pill (parallel to .tag-pick but smaller and editorial-toned),
 * marking that the record was published by a CannaDB editor account.
 * Sized to match the retuned trust-tier badges so the clarity signals
 * stay subordinate to community engagement on the card. */
.tag-seeded {
    background: var(--color-editorial-soft);
    color: var(--color-editorial);
    font-size: var(--text-2xs);
    padding: 0.05rem var(--space-2);
    font-weight: var(--weight-medium);
    text-transform: lowercase;
    letter-spacing: 0;
}
/* Catalog-kind aliases. Most indexed strains are recorded as kind=strain
 * (lean spectrum lives in IndicaSativaPct, not on cards), so we default
 * to the hybrid green; cuts ride the dedicated rust cut palette so
 * Sage's-Pick pink stays unique to editorially highlighted picks. */
.tag-strain { background: var(--color-tag-hybrid-bg); color: var(--color-tag-hybrid-fg); }
.tag-cut    { background: var(--color-cut-bg);        color: var(--color-cut-fg);     }
/* Neutral role tag — used where the chip names a *role* rather than a
 * lean/effect/pick (currently: "breeder" on the breeder hero). Sits
 * quietly in the warm-neutral surface family so it doesn't compete with
 * the lean tags or the Sage's-Pick badge for attention. */
.tag-role   { background: var(--color-bg-cream);      color: var(--color-fg-muted);   }

.tag-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: center;
}

/* ─── Lineage tree (connected boxes) ───────────────────────────
 * Tier visualization on the strain detail page hero. Coexists
 * with the legacy UL/LI .lineage-tree pattern on lineage.html
 * (reconciled in Phase 3): the legacy rules above target nested
 * ul/li, while this set targets .lineage-tree-row / .lineage-node
 * children, so the two render contexts do not collide.
 *
 * Connector lines are pseudo-elements where possible per spec;
 * .lineage-edge is available for explicit cases.
 */
.lineage-tree-row {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-3);
    position: relative;
}
.lineage-tree-row + .lineage-tree-row {
    margin-top: var(--space-4);
}
.lineage-tree-row + .lineage-tree-row::before {
    content: "";
    position: absolute;
    top: calc(-1 * var(--space-4));
    left: 50%;
    width: 1px;
    height: var(--space-4);
    background: var(--color-border-strong);
}
.lineage-node {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-2) var(--space-4);
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    color: var(--color-fg);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    text-align: center;
    min-width: 8rem;
    text-decoration: none;
    transition: border-color var(--duration) var(--easing), background var(--duration) var(--easing);
}
.lineage-node:hover { border-color: var(--color-border-strong); text-decoration: none; }
.lineage-node-self {
    background: var(--color-tag-hybrid-bg);
    color: var(--color-tag-hybrid-fg);
    border-color: var(--color-tag-hybrid-fg);
    font-weight: var(--weight-semibold);
}
.lineage-node-parent {
    background: var(--color-bg-cream);
    border-color: var(--color-border-strong);
    color: var(--color-fg);
}
.lineage-node-grandparent {
    background: var(--color-bg-elev);
    color: var(--color-fg-muted);
}
.lineage-edge {
    display: block;
    height: var(--space-4);
    width: 1px;
    background: var(--color-border-strong);
    margin: 0 auto;
}

/* ─── Effects bars (trait chart) ───────────────────────────────
 * Single-color fills on a lavender track. Labels and values in
 * Inter — the bars never use Bagel Fat One.
 */
.effects-bars {
    list-style: none;
    margin: var(--space-4) 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}
.effects-bar {
    display: grid;
    grid-template-columns: 8rem 1fr 3rem;
    align-items: center;
    gap: var(--space-3);
    font-size: var(--text-sm);
}
.effects-bar-label { color: var(--color-fg); }
.effects-bar-track {
    height: 0.5rem;
    background: var(--color-bg-lavender);
    border-radius: var(--radius-pill);
    overflow: hidden;
}
.effects-bar-fill {
    display: block;
    height: 100%;
    background: var(--color-fg-muted);
    border-radius: var(--radius-pill);
    transition: width var(--duration) var(--easing);
}
.effects-bar-value {
    color: var(--color-fg-muted);
    text-align: right;
    font-variant-numeric: tabular-nums;
}
@media (max-width: 30rem) {
    .effects-bar { grid-template-columns: 6rem 1fr 2.5rem; }
}

/* ─── Review card ──────────────────────────────────────────────
 * Avatar circle (initials fallback) + reviewer handle + rating +
 * body + helpful-count meta. Avatar background uses the tag-color
 * families for visual variety, picked per-reviewer at template
 * time (e.g. a hybrid-grower reviewer gets .review-avatar-hybrid).
 */
.review-card {
    display: flex;
    gap: var(--space-3);
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-4);
    margin: var(--space-3) 0;
}
.review-card-avatar {
    flex-shrink: 0;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--color-tag-hybrid-bg);
    color: var(--color-tag-hybrid-fg);
    font-weight: var(--weight-semibold);
    font-size: var(--text-base);
    text-transform: uppercase;
}
.review-avatar-hybrid { background: var(--color-tag-hybrid-bg); color: var(--color-tag-hybrid-fg); }
.review-avatar-indica { background: var(--color-tag-indica-bg); color: var(--color-tag-indica-fg); }
.review-avatar-sativa { background: var(--color-tag-sativa-bg); color: var(--color-tag-sativa-fg); }
.review-avatar-pick   { background: var(--color-tag-pick-bg);   color: var(--color-tag-pick-fg); }
/* Real <img> avatar variant: same circle dimensions as the colored
 * fallback, but shows the publisher's profile picture. object-fit
 * crops portrait/landscape avatars to a clean disc. */
.review-card-avatar-img {
    object-fit: cover;
    background: transparent;
}
.review-card-displayname {
    font-weight: var(--weight-semibold);
    color: var(--color-fg);
}
.review-card-handle-sub {
    color: var(--color-fg-muted);
    font-size: var(--text-xs);
    margin-left: var(--space-2);
}
.review-card-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}
.review-card-header {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    flex-wrap: wrap;
}
.review-card-handle {
    font-weight: var(--weight-semibold);
    color: var(--color-fg);
}
.review-card-rating {
    color: var(--color-brand-yellow-deep);
    letter-spacing: 0.1em;
    font-size: var(--text-sm);
    line-height: 1;
}
.review-card-text {
    margin: var(--space-1) 0 0;
    color: var(--color-fg-soft);
    line-height: var(--leading-snug);
}
.review-card-meta {
    font-size: var(--text-xs);
    color: var(--color-fg-muted);
    margin-top: var(--space-2);
}

/* ─── Related rail ─────────────────────────────────────────────
 * The horizontal "Try next" / "Strains by this breeder" /
 * "Recently indexed" surface. Scrolls horizontally on narrow
 * viewports, wraps to a static row on desktop.
 */
.related-rail {
    background: var(--color-bg-cream);
    border-radius: var(--radius-lg);
    padding: var(--space-5);
    margin: var(--space-6) 0;
}
.related-rail-header {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
    flex-wrap: wrap;
}
.related-rail-heading {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    flex: 1;
    min-width: 14rem;
}
.related-rail-heading .related-rail-intro { min-width: 0; }
.related-rail-header h2,
.related-rail-header h3 {
    margin: 0;
    font-size: var(--text-xl);
}
.related-rail-intro {
    color: var(--color-fg);
    font-size: var(--text-sm);
    margin: 0;
}
.related-rail-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    gap: var(--space-3);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
}
.related-rail-list > li {
    scroll-snap-align: start;
    flex: 0 0 16rem;
}
@media (min-width: 60rem) {
    .related-rail-list {
        overflow-x: visible;
        flex-wrap: wrap;
    }
}

/* ─── Empty state ──────────────────────────────────────────────
 * Composition for "we couldn't find that" surfaces. Used by
 * error.html (Phase 2) and various search/list empty bodies.
 * Defaults to the sleepy Sage; templates override the .sage-avatar
 * src for amazed / curious states as fitting.
 */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: var(--space-7) var(--space-4);
    gap: var(--space-3);
}
.empty-state .sage-avatar { margin-bottom: var(--space-2); }
.empty-state-title {
    margin: 0;
    font-size: var(--text-2xl);
    color: var(--color-fg-strong);
}
.empty-state-body {
    margin: 0;
    max-width: var(--max-width-prose);
    color: var(--color-fg-muted);
    line-height: var(--leading-snug);
}

/* ─── Publishing wait page ─────────────────────────────────────
 * The post-publish placeholder shown while the AppView indexer
 * catches up. Reuses .empty-state for layout; adds a spinning
 * disk so the user has a "something is happening" signal beyond
 * the static copy. Uses the existing ref-spin keyframes so we
 * don't add a parallel animation.
 */
.publishing-spinner {
    display: inline-block;
    width: 2.5rem;
    height: 2.5rem;
    border: 4px solid var(--color-border-strong);
    border-top-color: var(--color-accent);
    border-radius: 50%;
    animation: ref-spin 0.9s linear infinite;
}

/* ─── Buttons retuned + secondary variant ──────────────────────
 * Primary CTA is brand-ink fill with brand-yellow text; secondary
 * is outline-only with brand-ink text. Both pill-shaped per the
 * brand convention. These rules sit after the original button
 * block so they win on conflicting properties.
 */
.btn.btn-primary, .btn-primary {
    background: var(--color-brand-ink);
    border-color: var(--color-brand-ink);
    color: var(--color-brand-yellow);
    border-radius: var(--radius-pill);
    font-weight: var(--weight-semibold);
    padding: var(--space-2) var(--space-5);
}
.btn.btn-primary:hover, .btn-primary:hover {
    background: var(--color-fg-strong);
    border-color: var(--color-fg-strong);
    color: var(--color-brand-yellow);
}
.btn-secondary {
    /* inline-flex (vs inline-block) so single-line button text is
       optically centered. Inter reserves descender space in its
       line-box, so descender-free copy ("Cancel", "Edit") visually
       drifts above center inside an inline-block. align-items:
       center pins it. Border + fg use --color-fg so the button is
       readable in both themes — --color-brand-ink is fixed across
       modes and reads as disabled when it lands on dark-plum bg. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: inherit;
    font-size: var(--text-sm);
    line-height: 1.2;
    background: var(--color-bg-elev);
    border: 1px solid var(--color-fg);
    color: var(--color-fg);
    border-radius: var(--radius-pill);
    font-weight: var(--weight-semibold);
    padding: var(--space-2) var(--space-5);
    cursor: pointer;
    text-decoration: none;
    transition: background var(--duration) var(--easing), color var(--duration) var(--easing), border-color var(--duration) var(--easing);
}
.btn-secondary:hover {
    background: var(--color-bg-cream);
    color: var(--color-fg);
    border-color: var(--color-fg);
    text-decoration: none;
}

/* ──────────────────────────────────────────────────────────────
 * Phase 3.7 — Detail pages (Phase 3 of the redesign sprint)
 *
 * Shared chrome for strain + breeder detail-page heroes, plus
 * lineage / versions restyling. The `.entity-hero` block composes
 * Phase 1 component classes (.sticker, .tag, sage avatars) into
 * the marquee surface defined in brand-identity.md. The lineage
 * and versions blocks below restyle the existing markup to use
 * the new palette — graph layout logic in lineage.js is unchanged
 * other than the palette retune.
 * ────────────────────────────────────────────────────────────── */

/* Detail-page hero composition ─────────────────────────────────
 * Used by both strain.html and breeder.html. Left column: sticker
 * name + tag row + meta lines + CTAs. Right column: kind-colored
 * photo placeholder. Stacks vertically below 50rem.
 */
.entity-hero {
    display: flex;
    align-items: stretch;
    gap: var(--space-5);
    padding: var(--space-5);
    margin: 0 0 var(--space-5);
    background: var(--color-bg-cream);
    border-radius: var(--radius-lg);
    flex-wrap: wrap;
}
.entity-hero-copy {
    flex: 1 1 24rem;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    align-items: flex-start;
}
.entity-hero-name {
    margin: 0 0 var(--space-1);
    max-width: 100%;
    overflow-wrap: break-word;
    word-break: break-word;
    line-height: 1.05;
}
.entity-hero-tags {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: center;
    list-style: none;
    margin: 0;
    padding: 0;
}
.entity-hero-tags > li {
    display: inline-flex;
    align-items: center;
}
.entity-hero-meta-item {
    font-size: var(--text-xs);
    color: var(--color-fg-muted);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    font-weight: var(--weight-semibold);
}
.entity-hero-line {
    margin: 0;
    color: var(--color-fg-soft);
    font-size: var(--text-sm);
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1) var(--space-2);
    align-items: baseline;
}
.entity-hero-line .meta-label {
    font-size: var(--text-xs);
    color: var(--color-fg-faint);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    font-weight: var(--weight-semibold);
}
.entity-hero-line a { color: var(--color-fg); text-decoration: underline; text-decoration-color: var(--color-border-strong); }
.entity-hero-line a:hover { color: var(--color-fg-strong); text-decoration-color: var(--color-fg-muted); }
.entity-hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-top: var(--space-3);
}
.entity-hero-photo {
    flex: 0 0 12rem;
    align-self: stretch;
    min-height: 12rem;
    background: var(--color-bg-cream);
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
}
.entity-hero-photo-hybrid { background: var(--color-tag-hybrid-bg); border-color: var(--color-tag-hybrid-fg); }
.entity-hero-photo-indica { background: var(--color-tag-indica-bg); border-color: var(--color-tag-indica-fg); }
.entity-hero-photo-sativa { background: var(--color-tag-sativa-bg); border-color: var(--color-tag-sativa-fg); }
.entity-hero-photo-cut    { background: var(--color-cut-bg);        border-color: var(--color-cut-border); }
.entity-hero-photo-breeder { background: var(--color-bg-lavender); border-color: var(--color-border-strong); }
/* Real-photo variant: identical box dimensions to the kind-colored
 * placeholder above so the hero layout is stable whether the
 * publisher carried a primaryImage blob or not. cover keeps the
 * subject filling the box without distortion. */
.entity-hero-photo-img {
    object-fit: cover;
    width: auto;
    background: var(--color-bg-sunken);
}
@media (max-width: 50rem) {
    .entity-hero { padding: var(--space-4); gap: var(--space-4); }
    .entity-hero-photo { flex-basis: 100%; min-height: 8rem; }
}

/* Strain-name hero overrides — sticker treatment at hero scale.
 * The .sticker class supplies the bubble-letter visual; here we
 * size to the hero range (--text-4xl..--text-5xl) with line-height
 * tuned for readable wrapping on long strain names.
 */
.entity-hero-name.sticker {
    font-size: var(--text-5xl);
    line-height: var(--leading-tight);
}
@media (max-width: 50rem) {
    .entity-hero-name.sticker { font-size: var(--text-4xl); }
}
@media (max-width: 30rem) {
    .entity-hero-name.sticker { font-size: var(--text-3xl); }
}

/* Strain lineage tree section (composes Phase 1 .lineage-tree-row /
 * .lineage-node classes). Adds the vertical rhythm and the
 * "see full lineage" link styling. */
.strain-lineage { margin: var(--space-6) 0; }
.strain-lineage h2 { margin-bottom: var(--space-4); }
.strain-lineage-more {
    margin-top: var(--space-4);
    text-align: center;
    font-size: var(--text-sm);
}
.strain-lineage-more a { color: var(--color-fg-muted); }

/* Sticker-treatment section headers on detail pages. Default
 * margin recovers a touch of breathing room since the sticker
 * font sits taller than Inter. */
.sticker.sticker-h1, .sticker.sticker-h2, .sticker.sticker-h3 {
    margin: var(--space-6) 0 var(--space-3);
}
.entity-hero-copy .sticker.sticker-h1 { margin: 0 0 var(--space-1); }

/* ─── Lineage page restyle ─────────────────────────────────────
 * The legacy UL/LI ancestor tree is preserved (Go-side recursion
 * is out of scope), but the boxes now read as connected nodes
 * rather than flat list rows.
 */
.lineage-page .lineage-link,
.lineage-page .lineage-fallback {
    display: inline-block;
    padding: var(--space-1) var(--space-3);
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    color: var(--color-fg);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    text-decoration: none;
    transition: border-color var(--duration) var(--easing);
    margin: var(--space-1) 0;
}
.lineage-page .lineage-link:hover {
    text-decoration: none;
    border-color: var(--color-border-strong);
}
.lineage-page .lineage-fallback {
    color: var(--color-fg-muted);
    font-style: italic;
    border-style: dashed;
    border-bottom: 1px dashed var(--color-fg-faint);
}
.lineage-page .lineage-tree > li > .lineage-link,
.lineage-page .lineage-tree > li > .lineage-fallback {
    background: var(--color-tag-hybrid-bg);
    color: var(--color-tag-hybrid-fg);
    border-color: var(--color-tag-hybrid-fg);
    font-weight: var(--weight-semibold);
    font-size: var(--text-base);
}
.lineage-page .lineage-tree ul {
    border-left: 1px solid var(--color-border-strong);
}
.lineage-page .lineage-tree ul li::before {
    background: var(--color-border-strong);
}

.lineage-page .legend-editorial {
    border-color: var(--color-editorial);
    background: var(--color-editorial-soft);
}
.lineage-page .legend-community {
    border-color: var(--color-community);
    background: var(--color-community-soft);
    border-style: dashed;
}
.lineage-page .legend-cut {
    border-color: var(--color-tag-pick-fg);
    background: var(--color-tag-pick-bg);
}

/* ─── Versions page restyle ────────────────────────────────────
 * Sticker section headers on the forward/reverse lists. The
 * direction label sits as an eyebrow above the heading.
 */
.versions-block { margin: var(--space-6) 0; }
.versions-block .versions-direction {
    display: block;
    font-size: var(--text-xs);
    color: var(--color-fg-muted);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    font-weight: var(--weight-semibold);
    margin-bottom: var(--space-1);
}
.versions-block h2 { margin: 0 0 var(--space-3); }

/* ──────────────────────────────────────────────────────────────
 * Phase 3.7 — Browse / search surfaces (Phase 4 of the redesign)
 *
 * Strain and breeder cards become the canonical small-card shape:
 * a kind-colored thumb band on top, name in Inter Black (NOT
 * sticker — that's reserved for hero on detail pages), key tags
 * inline, and a meta line. List/search pages adopt sticker page
 * headers and pill-shaped filter controls. Suggestion overlay and
 * typeahead get a quiet styling pass per the handoff (no
 * brand-loud elements on functional surfaces).
 * ────────────────────────────────────────────────────────────── */

/* Card padding override — the old .card { padding: var(--space-4) }
 * still applies to other surfaces (review-card, cluster-card etc),
 * but strain/breeder cards now carry an edge-flush thumb so
 * padding moves to the inner body. */
.card.strain-card,
.card.breeder-card {
    padding: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.strain-card-thumb,
.breeder-card-thumb {
    display: flex;
    align-items: center;
    /* Right padding clears the absolutely-positioned like overlay
     * (sm variant ≈ 40px, anchored at space-2 from the edge). */
    padding: var(--space-2) calc(var(--space-2) + 2.75rem) var(--space-2) var(--space-4);
    background: var(--color-bg-cream);
    border-bottom: 1px solid var(--color-border);
    color: var(--color-fg-strong);
}
/* Lean-bucket variants. The card template prefers LeanBucket
 * (indica/sativa/hybrid, computed from IndicaSativaPct at card-build
 * time) and falls through to Kind when no lean is recorded. The
 * `color` here drives the title link inside the header — paired
 * fg/bg tag tokens are AA-tested, so the title reads in both themes
 * (the bg tokens are not theme-aware, so default fg-strong would
 * fail in dark mode). */
.strain-card-thumb-strain,
.strain-card-thumb-hybrid { background: var(--color-tag-hybrid-bg); border-bottom-color: var(--color-tag-hybrid-fg); color: var(--color-tag-hybrid-fg); }
.strain-card-thumb-indica { background: var(--color-tag-indica-bg); border-bottom-color: var(--color-tag-indica-fg); color: var(--color-tag-indica-fg); }
.strain-card-thumb-sativa { background: var(--color-tag-sativa-bg); border-bottom-color: var(--color-tag-sativa-fg); color: var(--color-tag-sativa-fg); }
.strain-card-thumb-cut    { background: var(--color-tag-pick-bg);   border-bottom-color: var(--color-tag-pick-fg);   color: var(--color-tag-pick-fg); }
.breeder-card-thumb       { background: var(--color-bg-lavender);   border-bottom-color: var(--color-border-strong); }

.strain-card-body,
.breeder-card-body {
    padding: var(--space-3) var(--space-4) var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    flex: 1;
}
.strain-card-name,
.breeder-card-name {
    margin: 0;
    font-size: var(--text-xl);
    font-weight: var(--weight-black);
    /* The title now lives inside the colored band header; inherit
     * its `color` so each lean variant's matched fg token drives
     * the link color (AA-tested against its own bg, in both themes). */
    color: inherit;
    letter-spacing: var(--tracking-tight);
    line-height: var(--leading-snug);
    min-width: 0;
}
.strain-card-name a,
.breeder-card-name a {
    color: inherit;
    text-decoration: none;
}
.strain-card-name a:hover,
.breeder-card-name a:hover {
    text-decoration: underline;
}
.strain-card-tags,
.breeder-card-tags {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    align-items: center;
}
.strain-card-byline,
.breeder-card-byline {
    margin: 0;
    color: var(--color-fg-muted);
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
}
.strain-card-byline a {
    color: var(--color-fg);
    text-decoration: none;
    border-bottom: 1px solid var(--color-border-strong);
}
.strain-card-byline a:hover {
    color: var(--color-fg-strong);
    border-bottom-color: var(--color-fg-muted);
}
.strain-card-excerpt {
    margin: 0;
    color: var(--color-fg-soft);
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
    margin-top: auto;
}
/* Search-result similarity: a quiet meta line between byline and
 * excerpt. Tabular numerals so the percentages right-edge align
 * across cards. Only renders when the card model carries a
 * Similarity (search results); empty otherwise. */
.strain-card-similarity {
    margin: 0;
    color: var(--color-fg-muted);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
}

/* List filter pills ──────────────────────────────────────────
 * Existing .kind-option already pill-shaped; retune the active
 * state to the brand-ink + brand-yellow contrast pair, matching
 * the .btn-primary inversion. Inactive state stays quiet.
 */
.kind-option {
    transition: background var(--duration) var(--easing), color var(--duration) var(--easing), border-color var(--duration) var(--easing);
    font-weight: var(--weight-medium);
}
.kind-option.is-active {
    background: var(--color-brand-ink);
    color: var(--color-brand-yellow);
    border-color: var(--color-brand-ink);
}
.kind-option:hover { border-color: var(--color-border-strong); }
.kind-option.is-active:hover { border-color: var(--color-brand-ink); }

/* Pagination: pill button vocabulary matching the rest of the chrome. */
.pagination .btn,
.pagination .btn-secondary {
    border-radius: var(--radius-pill);
}

/* List + search header restyle: sticker page headers ────────── */
.list-page .list-header h1.sticker,
.search-page h1.sticker { margin: 0 0 var(--space-2); }
.list-page .list-header,
.search-page header {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-3);
    border-bottom: 1px solid var(--color-border);
    padding-bottom: var(--space-3);
    margin-bottom: var(--space-4);
}
.search-page header .lede {
    color: var(--color-fg-muted);
    font-size: var(--text-base);
    margin: 0;
}

/* Search-suggestions overlay — quiet polish ─────────────────── */
.search-suggestions a {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}
.search-suggestions a:hover { background: var(--color-bg-lavender); }
.search-suggestions a strong { color: var(--color-fg-strong); font-weight: var(--weight-semibold); }
.suggest-kind {
    display: inline-block;
    width: 0.6rem;
    height: 0.6rem;
    border-radius: 50%;
    flex-shrink: 0;
    background: var(--color-fg-faint);
}
.suggest-kind-strain { background: var(--color-tag-hybrid-fg); }
.suggest-kind-cut    { background: var(--color-tag-pick-fg); }

/* Typeahead hover retune — lavender accent, not brand-yellow.
 * Brand-yellow accent on a typeahead item is a brand-loud signal
 * the handoff explicitly rules out for functional surfaces. */
.typeahead-result:hover,
.typeahead-result.is-active {
    background: var(--color-bg-lavender);
    border-color: var(--color-border-strong);
}

/* ──────────────────────────────────────────────────────────────
 * Phase 3.7 — User & forms (Phase 5 of the redesign sprint)
 *
 * Login, me / me-records dashboards, and the strain/breeder forms.
 * The handoff is explicit: "this is a styling pass, not a form
 * rewrite." Field labels, aria-invalid, .field-error spans, and
 * the markdown / ref-field HTMX wires all pass through unchanged.
 * ────────────────────────────────────────────────────────────── */

/* Auth page hero composition — login.html. The Sage's-Note
 * callout sits above the handle-entry form, introducing the
 * sign-in flow with a one-sentence note. The form itself uses
 * the form-page max-width. */
.auth-page {
    max-width: var(--max-width-form);
}
.auth-page h1.sticker { margin: 0 0 var(--space-3); }
.auth-page .sage-note { margin-bottom: var(--space-4); }
.auth-page .auth-form {
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-4);
    margin-top: var(--space-4);
}
.auth-page .auth-form button[type="submit"] {
    background: var(--color-brand-ink);
    border-color: var(--color-brand-ink);
    color: var(--color-brand-yellow);
    border-radius: var(--radius-pill);
    font-weight: var(--weight-semibold);
    padding: var(--space-2) var(--space-5);
    border: 1px solid var(--color-brand-ink);
    cursor: pointer;
    font-size: var(--text-sm);
    transition: background var(--duration) var(--easing);
}
.auth-page .auth-form button[type="submit"]:hover {
    background: var(--color-fg-strong);
    border-color: var(--color-fg-strong);
}

/* Atmosphere explainer ────────────────────────────────────────
 * Sits below the auth-form on login.html. Tells incoming users
 * what an Atmosphere account is, samples a few sibling apps that
 * share the network, and points to ATStore for full discovery.
 * Cream surface so it reads as a distinct, friendly aside from
 * the elevated white auth-form above it; sage-aha avatar in the
 * header pairs with the "wait, what's…" framing.
 */
.atmos-explainer {
    margin-top: var(--space-6);
    background: var(--color-bg-cream);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-5);
}
.atmos-explainer-header {
    display: flex;
    gap: var(--space-3);
    align-items: center;
    margin-bottom: var(--space-3);
}
.atmos-explainer-eyebrow {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--color-fg-muted);
    font-weight: var(--weight-semibold);
    margin: 0 0 var(--space-1);
    line-height: 1;
}
.atmos-explainer-title {
    font-size: var(--text-xl);
    font-weight: var(--weight-bold);
    color: var(--color-fg-strong);
    margin: 0;
    line-height: var(--leading-snug);
}
.atmos-explainer-text {
    font-size: var(--text-sm);
    line-height: var(--leading-prose);
    color: var(--color-fg);
    margin: 0 0 var(--space-4);
}
.atmos-explainer-text code {
    font-size: 0.9em;
    background: var(--color-bg-elev);
    padding: 0.05em 0.35em;
    border-radius: var(--radius-sm);
}
.atmos-explainer-subhead {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--color-fg-muted);
    font-weight: var(--weight-semibold);
    margin: 0 0 var(--space-2);
}
.atmos-app-grid {
    list-style: none;
    margin: 0 0 var(--space-4);
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
    gap: var(--space-2);
}
.atmos-app-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: var(--space-1);
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-2);
    color: var(--color-fg);
    text-decoration: none;
    min-height: 4.5rem;
    transition: border-color var(--duration) var(--easing), transform var(--duration) var(--easing);
}
.atmos-app-tile:hover {
    text-decoration: none;
    border-color: var(--color-border-strong);
    transform: translateY(-1px);
}
.atmos-app-tile-self {
    background: var(--color-accent-soft);
    border-color: var(--color-accent);
}
.atmos-app-name {
    font-weight: var(--weight-semibold);
    color: var(--color-fg-strong);
    font-size: var(--text-sm);
}
.atmos-app-blurb {
    font-size: var(--text-xs);
    color: var(--color-fg-muted);
}
.atmos-explainer-discover {
    font-size: var(--text-sm);
    color: var(--color-fg-soft);
    margin: 0 0 var(--space-4);
    line-height: var(--leading-snug);
}
.atmos-cta {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-brand-yellow);
    border: 1px solid var(--color-brand-yellow-deep);
    color: var(--color-brand-ink);
    text-decoration: none;
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    font-weight: var(--weight-semibold);
    font-size: var(--text-sm);
    transition: background var(--duration) var(--easing), transform var(--duration) var(--easing);
}
.atmos-cta:hover {
    background: var(--color-brand-yellow-deep);
    text-decoration: none;
    transform: translateY(-1px);
}

/* FAQ page ────────────────────────────────────────────────────
 * Long-form prose page with anchored sections. Mirrors the
 * auth-page composition (sticker h1, Sage's-Note callout) but
 * widens to the prose max so the question/answer pairs read
 * comfortably without forcing one-line paragraphs.
 */
.faq-page { max-width: var(--max-width-prose); }
.faq-page h1.sticker { margin: 0 0 var(--space-2); }
.faq-header { margin-bottom: var(--space-3); }
.faq-lede {
    color: var(--color-fg-muted);
    font-size: var(--text-lg);
    margin: 0;
}
.faq-page .sage-note { margin-bottom: var(--space-5); }
.faq-toc {
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
    margin-bottom: var(--space-6);
}
.faq-toc-title {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--color-fg-muted);
    font-weight: var(--weight-semibold);
    margin: 0 0 var(--space-2);
}
.faq-toc ul {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
    gap: var(--space-1) var(--space-4);
}
.faq-toc a {
    display: inline-block;
    padding: var(--space-1) 0;
    font-size: var(--text-sm);
}
.faq-section {
    /* Anchor target offset so in-page jumps clear the sticky-feeling
     * header padding and the section heading lands below the nav band
     * rather than tight against it. */
    scroll-margin-top: var(--space-5);
    margin-bottom: var(--space-7);
}
.faq-section + .faq-section {
    border-top: 1px solid var(--color-border);
    padding-top: var(--space-5);
}
.faq-section h2.sticker { margin: 0 0 var(--space-3); }
.faq-section h3 {
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
    color: var(--color-fg-strong);
    margin: var(--space-4) 0 var(--space-1);
}
.faq-section p,
.faq-section ul,
.faq-section ol {
    margin: 0 0 var(--space-3);
    line-height: var(--leading-prose);
}
.faq-section ul,
.faq-section ol { padding-left: var(--space-5); }
.faq-section code {
    font-size: 0.9em;
    background: var(--color-bg-sunken);
    padding: 0.1em 0.35em;
    border-radius: var(--radius-sm);
}

/* Footer nav ──────────────────────────────────────────────────
 * Right-aligned link cluster opposite the site tagline. The
 * existing .footer-inner is a flex with space-between, so the
 * nav drops in without further alignment work.
 */
.footer-nav { display: flex; gap: var(--space-4); flex-wrap: wrap; }
.footer-nav a { color: inherit; }

/* Me dashboard — Phase 5 ─────────────────────────────────────
 * Sticker h1, Sage's-Note welcome moment, action-button grid,
 * sticker-treatment rail headings.
 */
.me-page h1.sticker { margin: 0 0 var(--space-2); }
.me-page .me-header {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-4);
    align-items: flex-start;
    border-bottom: 1px solid var(--color-border);
    padding-bottom: var(--space-4);
    margin-bottom: var(--space-4);
}
.me-page .me-header .profile-avatar { flex-shrink: 0; }
.me-page .me-identity {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    align-items: flex-start;
    min-width: 0;
    flex: 1;
}
.me-page .me-header .me-meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    align-items: center;
    font-size: var(--text-sm);
    color: var(--color-fg-muted);
    margin: 0;
}
.me-page .me-header .me-meta code {
    font-size: var(--text-xs);
    word-break: break-all;
}
.me-page .me-header .logout-form { margin-left: auto; }
.me-page .me-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-bottom: var(--space-5);
}
.me-page .sage-note { margin: 0 0 var(--space-5); }
/* Generalized rail heading override — applies on /me, /editor, and
 * any other page that puts a sticker section header inside a rail. */
.rail h2.sticker,
.rail h3.sticker { margin: 0 0 var(--space-3); }

/* Form chrome (Phase 5) ──────────────────────────────────────
 * Sticker treatment on form-page h1; restyled summary headings
 * on form-section disclosure widgets; pill-shape submit button
 * and outline-pill secondary action.
 */
.form-page h1.sticker { margin: 0 0 var(--space-4); }
.form-page > h1 { margin-bottom: var(--space-4); }
.form-section > summary {
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
}
.form-section > summary:hover { background: var(--color-bg-cream); }
fieldset.form-section > legend {
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--color-fg-strong);
}
.form-section.form-required > legend::after {
    content: "  required";
    color: var(--color-fg-faint);
    font-weight: var(--weight-regular);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    font-size: var(--text-xs);
    margin-left: var(--space-2);
}

/* Form-page error block — top-of-form summary ───────────────── */
.form-page .alert.alert-error ul {
    margin: var(--space-2) 0 0;
    padding-left: var(--space-5);
}

/* ref-field state chips retuned to clean tokens ──────────── */
.ref-row.is-linked .ref-linked-chip {
    background: var(--color-editorial-soft);
    border-color: var(--color-editorial);
    color: var(--color-editorial);
}
.ref-row.is-fallback .ref-fallback-chip {
    background: var(--color-community-soft);
    border-color: var(--color-community);
    color: var(--color-community);
}

/* Markdown editor tab active state retune ─────────────────── */
.md-tab:focus-visible {
    outline: 2px solid var(--color-focus);
    outline-offset: 2px;
}
.md-tab.is-active {
    background: var(--color-bg-cream);
    border-color: var(--color-border-strong);
    color: var(--color-fg-strong);
    font-weight: var(--weight-semibold);
}
.md-editor:focus-within {
    border-color: var(--color-border-strong);
    box-shadow: 0 0 0 3px var(--color-bg-lavender);
}

/* ──────────────────────────────────────────────────────────────
 * Phase 3.7 — Editor surfaces (Phase 6 of the redesign sprint)
 *
 * Light pass per the handoff. Sticker treatment on top-level page
 * headers; everything else stays direct, dense, and operational.
 * The existing .editor-* / .cluster-* / .canon-* / .stat-grid
 * rules are already token-driven; nothing else needed retuning.
 * ────────────────────────────────────────────────────────────── */

.editor-header h1.sticker { margin: 0 0 var(--space-2); }
.editor-header { margin-bottom: var(--space-4); }

/* ────────────────────────────────────────────────────────────────
 * Phase 5.5 — Review modal, like button, stars, toast
 *
 * Three new component clusters:
 *   .like-button (+ -active / -disabled / -lg / -sm / -review variants)
 *   .review-form-modal + .review-form (stars input, photos, disclosure)
 *   .toast (success / error pop-up)
 *
 * Tokens-only (no hardcoded colors). Distinct focus rings on the star
 * radios so keyboard users can land on a star and see it clearly.
 * ──────────────────────────────────────────────────────────────── */

/* ─── Like button ────────────────────────────────────────────── */
.like-button {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-2);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-pill);
    background: var(--color-bg-elev);
    color: var(--color-fg-muted);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    cursor: pointer;
    transition:
        color var(--duration) var(--easing),
        background-color var(--duration) var(--easing),
        border-color var(--duration) var(--easing),
        transform var(--duration-fast) var(--easing);
}
.like-button:hover {
    color: var(--color-brand-yellow-deep);
    border-color: var(--color-brand-yellow-deep);
}
.like-button:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--color-accent-soft);
    border-color: var(--color-accent);
}
.like-button:active:not(.like-button-disabled) {
    transform: scale(0.96);
}
.like-button .like-icon {
    width: 1em;
    height: 1em;
    flex: none;
}
/* The filled overlay only paints when the button carries the active
 * state. Stroke remains visible underneath so the icon shape doesn't
 * pop in/out on toggle. */
.like-button .like-icon-fill {
    opacity: 0;
    transition: opacity var(--duration) var(--easing);
}
.like-button .like-icon-stroke {
    opacity: 1;
}
.like-button-active {
    color: var(--color-brand-yellow-deep);
    border-color: var(--color-brand-yellow-deep);
    background: var(--color-accent-soft);
}
.like-button-active .like-icon-fill { opacity: 1; }
.like-button-active .like-icon-stroke { opacity: 0; }

.like-button-disabled {
    cursor: not-allowed;
    color: var(--color-fg-faint);
    border-color: var(--color-border);
    background: var(--color-bg-sunken);
}
.like-button-disabled:hover {
    color: var(--color-fg-faint);
    border-color: var(--color-border);
}

/* Size variants. */
.like-button-sm { padding: 2px 8px; font-size: var(--text-xs); gap: 4px; }
.like-button-sm .like-icon { width: 14px; height: 14px; }
.like-button-lg { padding: var(--space-2) var(--space-3); font-size: var(--text-base); gap: var(--space-2); }
.like-button-lg .like-icon { width: 20px; height: 20px; }
.like-button-review { padding: 2px 10px; font-size: var(--text-xs); }
.like-button-review .like-label { margin-left: 2px; }

.like-button-error {
    display: inline-block;
    padding: 4px 10px;
    border-radius: var(--radius);
    background: var(--color-danger-bg);
    color: var(--color-danger);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
}

.reauth-notice {
    display: inline-block;
    padding: 4px 10px;
    border-radius: var(--radius);
    background: var(--color-warning-bg);
    color: var(--color-warning);
    font-size: var(--text-xs);
}

/* Strain card: like overlay anchored to top-right. */
.strain-card { position: relative; }
.strain-card-like-overlay {
    position: absolute;
    top: var(--space-2);
    right: var(--space-2);
    z-index: 1;
}

/* ─── Review form modal ──────────────────────────────────────── */
.review-form-modal {
    position: fixed;
    inset: 0;
    margin: auto;
    width: min(560px, 95vw);
    max-height: min(90vh, 760px);
    overflow: auto;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-lg);
    padding: 0;
    background: var(--color-bg-elev);
    color: var(--color-fg);
    box-shadow: var(--shadow-lg);
    z-index: var(--z-modal);
}
.review-form-modal::backdrop {
    /* Token override lives in tokens.css [data-theme="dark"] —
     * the default plum-tinted veil reads on light surfaces but
     * disappears against deep-plum chrome, where a stronger black
     * scrim is needed to dim the page behind the modal. */
    background: var(--color-modal-backdrop);
}
.review-form {
    padding: var(--space-5);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}
.review-form-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
    margin: 0;
}
.review-form-title { margin: 0; }
.review-form-help { margin: 0 0 var(--space-2); }
.review-form-close {
    background: transparent;
    border: none;
    color: var(--color-fg-muted);
    font-size: var(--text-2xl);
    line-height: 1;
    cursor: pointer;
    padding: 0 var(--space-2);
}
.review-form-close:hover { color: var(--color-fg); }
.review-form-actions {
    display: flex;
    gap: var(--space-3);
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: 1px solid var(--color-border);
}
/* Submit-button busy state: swap "Publish/Update review" for the
 * progress text while htmx has the request in flight. The .htmx-request
 * class lands on .review-form during the POST; hx-disabled-elt also
 * disables the button so a second click can't double-submit. */
.review-form-submit-busy { display: none; }
.review-form.htmx-request .review-form-submit-idle { display: none; }
.review-form.htmx-request .review-form-submit-busy { display: inline; }
.review-form-submit:disabled { cursor: progress; opacity: 0.7; }
.review-form-photos {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}
.review-form-photo-previews {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    list-style: none;
    padding: 0;
    margin: 0;
}
.review-form-photo-previews li {
    width: 84px;
    height: 84px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--color-bg-sunken);
    position: relative;
}
.review-form-photo-previews img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.strain-form-existing-image {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    align-items: flex-start;
    margin-bottom: var(--space-2);
}
.strain-form-existing-image img {
    max-width: 200px;
    max-height: 200px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-bg-sunken);
    object-fit: cover;
}

.review-form-disclosure { margin-top: var(--space-3); }
.review-form-axis-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4) var(--space-4);
}

/* ─── Star rating input ──────────────────────────────────────── */
/* Hide the underlying radios; the labels carry the visual + click
 * target. Focus-visible on the radio bumps the matching label. */
.rating-stars-input {
    border: none;
    margin: 0;
    padding: 0;
}
.rating-stars-input legend {
    font-weight: var(--weight-semibold);
    margin-bottom: var(--space-1);
    color: var(--color-fg-strong);
}
.rating-stars-row {
    display: inline-flex;
    flex-direction: row-reverse;
    gap: 2px;
}
.rating-stars-row input[type="radio"] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    border: 0;
}
.rating-stars-row label {
    cursor: pointer;
    color: var(--color-border-strong);
    transition: color var(--duration-fast) var(--easing);
    line-height: 1;
}
.rating-stars-row label .star-icon {
    width: 28px;
    height: 28px;
    display: block;
}
.rating-stars-input-sm .rating-stars-row label .star-icon { width: 22px; height: 22px; }
/* The reverse-row trick: hovering or selecting a label fills it AND every
 * preceding sibling (which renders to the left because flex-direction is
 * row-reverse). */
.rating-stars-row label:hover,
.rating-stars-row label:hover ~ label,
.rating-stars-row input[type="radio"]:checked ~ label {
    color: var(--color-brand-yellow-deep);
}
.rating-stars-row input[type="radio"]:focus-visible + label {
    outline: 2px solid var(--color-focus);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ─── Toast (success / error post-publish) ───────────────────── */
.toast {
    margin: var(--space-3) 0;
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius);
    font-size: var(--text-sm);
    box-shadow: var(--shadow-sm);
    border: 1px solid var(--color-border);
    background: var(--color-bg-elev);
    color: var(--color-fg);
}
.toast-success {
    background: var(--color-success-bg);
    border-color: var(--color-success-border);
    color: var(--color-success);
}
.toast-error {
    background: var(--color-danger-bg);
    border-color: var(--color-danger-border);
    color: var(--color-danger);
}

/* ─── Reviews section + signed-out CTA ───────────────────────── */
.entity-reviews {
    margin: var(--space-6) 0 var(--space-4);
}
.entity-reviews-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
    margin-bottom: var(--space-3);
}
.entity-reviews-summary {
    margin: 0;
    color: var(--color-fg-muted);
    font-size: var(--text-sm);
}
.entity-reviews-actions { margin: var(--space-2) 0; }
.review-signed-out-banner {
    margin: var(--space-3) 0;
    padding: var(--space-3) var(--space-4);
    border: 1px dashed var(--color-border-strong);
    border-radius: var(--radius);
    background: var(--color-bg-cream);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
}
.review-signed-out-banner p { margin: 0; max-width: 32rem; color: var(--color-fg-soft); }

@media (max-width: 30rem) {
    .review-form-modal { width: 100vw; max-height: 100vh; border-radius: 0; }
    .rating-stars-row label .star-icon { width: 32px; height: 32px; }
}

/* ────────────────────────────────────────────────────────────────
 * Phase 5.6 — Display surfaces
 *
 * Cultivation grid + pills, source eyebrow on effects, medicinal-effect
 * tag variant, parent-breeder attribution under lineage nodes, source-URL
 * footer, trending badge, review-card display affordances (helpful row,
 * photos, axis disclosure, read-more), home-page trending rail spacing.
 *
 * Most chrome already exists; this block fills the surface-specific gaps.
 * ──────────────────────────────────────────────────────────────── */

/* Hero meta line — rating + count rendered above the action buttons. */
.entity-hero-meta-line {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin: var(--space-2) 0 0;
    flex-wrap: wrap;
}
.entity-rating {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-sm);
    color: var(--color-fg-soft);
}
.entity-rating-text { font-weight: var(--weight-semibold); color: var(--color-fg-strong); }
.entity-rating-count { color: var(--color-fg-muted); font-weight: var(--weight-regular); }

/* Display-only star bar (vs the input variant in the review form).
 * Uses currentColor so the parent picks the active vs inactive shade —
 * see .star-icon-on for the filled state. */
.rating-stars.rating-stars-display {
    display: inline-flex;
    align-items: center;
    gap: 1px;
    color: var(--color-border-strong);
    line-height: 1;
}
.rating-stars.rating-stars-display .star-icon {
    width: 14px;
    height: 14px;
    display: inline-block;
}
.rating-stars.rating-stars-display .star-icon.star-icon-on {
    color: var(--color-brand-yellow-deep);
}
/* Half-star: the base path stays in the surrounding "off" color (the
 * container's currentColor) and a second <path class="star-icon-half-fill">
 * paints the left half in the on color. Used by ratingStarStates() in
 * templates.go so a 4.3 average renders as 4 full + 1 half rather than
 * collapsing to 4 (which contradicts the printf %.1f aria-label and
 * adjacent rating-text). */
.rating-stars.rating-stars-display .star-icon-half-fill {
    fill: var(--color-brand-yellow-deep);
    stroke: var(--color-brand-yellow-deep);
    clip-path: inset(0 50% 0 0);
}

/* Short description renders as a quiet lead paragraph above the full
 * About markdown, so the reader gets the elevator pitch first. */
.entity-short-description {
    color: var(--color-fg);
    font-weight: var(--weight-medium);
    font-size: var(--text-base);
    margin: 0 0 var(--space-3);
}

/* Genetics block ──────────────────────────────────────────────── */
.entity-genetics {
    margin: var(--space-4) 0;
}
.generation-badge {
    background: var(--color-bg-lavender);
    color: var(--color-fg-strong);
    border-radius: var(--radius-pill);
    padding: 2px var(--space-2);
    font-weight: var(--weight-semibold);
    font-size: var(--text-xs);
    letter-spacing: var(--tracking-wide);
}
.seed-availability-chip {
    background: var(--color-bg-sunken);
    border: 1px solid var(--color-border);
    color: var(--color-fg);
}

/* Cultivation block ───────────────────────────────────────────── */
.entity-cultivation { margin: var(--space-5) 0; }
.cultivation-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: var(--space-3) var(--space-4);
    margin: var(--space-3) 0;
    padding: 0;
    list-style: none;
}
.cultivation-field {
    background: var(--color-bg-elev);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
}
.cultivation-field > dt {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--color-fg-faint);
    font-weight: var(--weight-semibold);
    margin: 0 0 var(--space-1);
}
.cultivation-field > dd { margin: 0; }
.cultivation-field-value {
    font-size: var(--text-base);
    color: var(--color-fg-strong);
    font-weight: var(--weight-semibold);
    display: inline-block;
}
.cultivation-field-basis {
    display: inline-block;
    margin-left: var(--space-2);
    font-size: var(--text-xs);
    color: var(--color-fg-muted);
    font-style: italic;
    text-transform: lowercase;
}
.cultivation-pill {
    display: inline-block;
    padding: 2px var(--space-2);
    border-radius: var(--radius-pill);
    font-weight: var(--weight-semibold);
    font-size: var(--text-xs);
    background: var(--color-bg-cream);
    color: var(--color-fg-strong);
    border: 1px solid var(--color-border);
}
.cultivation-pill-difficulty-easy { background: var(--color-tag-sativa-bg); color: var(--color-tag-sativa-fg); border-color: var(--color-tag-sativa-fg); }
.cultivation-pill-difficulty-intermediate { background: var(--color-tag-hybrid-bg); color: var(--color-tag-hybrid-fg); border-color: var(--color-tag-hybrid-fg); }
.cultivation-pill-difficulty-hard { background: var(--color-tag-thc-bg); color: var(--color-tag-thc-fg); border-color: var(--color-tag-thc-fg); }
.cultivation-pill-odour-low { background: var(--color-bg-cream); color: var(--color-fg-soft); }
.cultivation-pill-odour-medium { background: var(--color-bg-lavender); color: var(--color-fg-strong); }
.cultivation-pill-odour-high { background: var(--color-tag-pick-bg); color: var(--color-tag-pick-fg); border-color: var(--color-tag-pick-fg); }
.cultivation-subhead {
    margin: var(--space-3) 0 var(--space-1);
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--color-fg-faint);
    font-weight: var(--weight-semibold);
}
.cultivation-characteristics .chip-list { margin-top: var(--space-1); }
.characteristic-chip {
    background: var(--color-bg-cream);
    color: var(--color-fg);
    border: 1px solid var(--color-border);
}
.cultivation-notes { margin-top: var(--space-3); }
@media (max-width: 30rem) {
    .cultivation-grid { grid-template-columns: 1fr; }
}

/* Effects-source eyebrow (community vs claimed) ───────────────── */
.effects-bars-source {
    margin: 0 0 var(--space-2);
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--color-fg-muted);
    font-weight: var(--weight-semibold);
}

/* Medicinal-effect tag — visual variant of .chip with a smaller, muted
 * treatment to distinguish it from recreational effect chips. */
.medicinal-effect-tag {
    background: var(--color-bg-elev);
    color: var(--color-fg-soft);
    border: 1px dashed var(--color-border);
    font-size: var(--text-xs);
    padding: 2px var(--space-2);
    text-transform: lowercase;
}

/* Lineage parent-breeder attribution — small italic credit beneath the
 * parent name (e.g. "Triangle Mints — Seed Junky Genetics"). Stacks
 * vertically with .lineage-node-wrap so each parent's attribution sits
 * directly under its node. */
.lineage-node-wrap {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    margin: 0 var(--space-2);
}
.parent-breeder-attribution {
    font-size: var(--text-xs);
    font-style: italic;
    color: var(--color-fg-muted);
    text-align: center;
    max-width: 12rem;
}

/* Trending badge — pill on cards in the trending top-N. Shares the
 * tag visual vocabulary but carries its own color so it stands apart
 * from kind tags. */
.trending-badge {
    display: inline-block;
    background: var(--color-brand-yellow);
    color: var(--color-brand-ink);
    border: 1px solid var(--color-brand-yellow-deep);
    border-radius: var(--radius-pill);
    padding: 2px var(--space-2);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
}

/* Source URL footer — small attribution at the bottom of the strain
 * page when the publisher provided a sourceUrl. */
.entity-source-footer {
    margin: var(--space-5) 0 var(--space-3);
    padding-top: var(--space-3);
    border-top: 1px dashed var(--color-border);
    font-size: var(--text-sm);
    color: var(--color-fg-muted);
}

/* Reviews list + read-more disclosure ─────────────────────────── */
.reviews-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
}
.review-card-text-disclosure {
    margin: var(--space-1) 0 0;
}
.review-card-text-disclosure > summary {
    cursor: pointer;
    color: var(--color-fg-soft);
    line-height: var(--leading-snug);
    list-style: none;
}
.review-card-text-disclosure > summary::-webkit-details-marker { display: none; }
.review-card-text-disclosure > summary::after {
    content: "  read more →";
    color: var(--color-accent);
    font-size: var(--text-xs);
    margin-left: var(--space-1);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
}
.review-card-text-disclosure[open] > summary::after { content: ""; }
.review-card-text-full {
    margin-top: var(--space-2);
    color: var(--color-fg);
}

.review-card-photos {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    list-style: none;
    padding: 0;
    margin: var(--space-2) 0 0;
}
.review-card-photo-thumb {
    display: block;
    width: 72px;
    height: 72px;
    border-radius: var(--radius);
    overflow: hidden;
    border: 1px solid var(--color-border);
    background: var(--color-bg-sunken);
}
.review-card-photo-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--duration) var(--easing);
}
.review-card-photo-thumb:hover img { transform: scale(1.05); }
.review-card-photo-thumb:focus-visible {
    outline: 2px solid var(--color-focus);
    outline-offset: 2px;
}

.review-card-tags {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-top: var(--space-2);
}
.review-card-tags .chip-list { margin: 0; }

.review-card-axes {
    margin-top: var(--space-2);
}
.review-card-axes > summary {
    cursor: pointer;
    color: var(--color-fg-muted);
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
}
.review-card-axis-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: var(--space-1) var(--space-3);
    margin: var(--space-2) 0 0;
    padding: 0;
}
.review-card-axis {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
}
.review-card-axis > dt {
    font-size: var(--text-xs);
    color: var(--color-fg-muted);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    margin: 0;
}
.review-card-axis > dd { margin: 0; }

.review-card-footer {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-top: var(--space-2);
    padding-top: var(--space-2);
    border-top: 1px solid var(--color-border);
}
.review-card-flag-slot { margin-left: auto; }

.reviews-show-more {
    margin: var(--space-3) auto 0;
    display: block;
}

.empty-state-reviews {
    background: var(--color-bg-cream);
    border-radius: var(--radius-md);
    margin: var(--space-3) 0;
    padding: var(--space-5) var(--space-4);
}

/* Home-page trending rail spacing — composes existing .related-rail with
 * the page-level rhythm. */
.home-trending-rail { margin-top: var(--space-5); }

/* ─── Phase 5.7 — Moderation surfaces ───────────────────────── */

/* Flag-this disclosure on review cards. The summary is intentionally tiny;
 * "more actions" should not invite attack — the affordance reveals on
 * intent (open the disclosure, click the button, fill the modal). */
.review-card-actions { position: relative; }
.review-card-actions[open] .review-card-actions-summary { color: var(--color-fg-muted); }
.review-card-actions-summary {
    list-style: none;
    cursor: pointer;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: var(--radius-pill);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--text-lg);
    line-height: 1;
    color: var(--color-fg-faint);
    transition: background-color var(--duration-fast) var(--easing);
}
.review-card-actions-summary::-webkit-details-marker { display: none; }
.review-card-actions-summary:hover,
.review-card-actions-summary:focus-visible {
    background: var(--color-bg-sunken);
    color: var(--color-fg);
}
.review-card-actions-body {
    position: absolute;
    right: 0;
    top: calc(100% + 0.25rem);
    z-index: var(--z-dropdown);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    padding: var(--space-2);
    min-width: 12rem;
}

.flag-button {
    background: transparent;
    border: 1px solid transparent;
    color: var(--color-fg-muted);
    font-size: var(--text-sm);
    cursor: pointer;
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
    text-align: left;
    width: 100%;
    transition: color var(--duration-fast) var(--easing), background-color var(--duration-fast) var(--easing);
}
.flag-button:hover,
.flag-button:focus-visible {
    color: var(--color-danger);
    background: color-mix(in oklab, var(--color-danger) 6%, transparent);
    outline: none;
    border-color: color-mix(in oklab, var(--color-danger) 20%, transparent);
}
.flag-button-error {
    display: inline-block;
    color: var(--color-danger);
    font-size: var(--text-sm);
    padding: var(--space-1) var(--space-2);
}

/* Flag form modal. Lives inside the review-card-actions-body slot so the
 * form sits in-context under the card; the disclosure stays open while
 * the modal is up. Cancel / submit drive the swap back. */
.flag-modal {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    min-width: 18rem;
}
.flag-modal-error {
    color: var(--color-danger);
    font-size: var(--text-sm);
    margin: 0;
}
.flag-modal-reasons {
    border: 0;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}
.flag-modal-reasons legend {
    font-weight: var(--weight-semibold);
    font-size: var(--text-sm);
    margin-bottom: var(--space-1);
    padding: 0;
}
.flag-modal-reason {
    display: flex;
    gap: var(--space-2);
    align-items: flex-start;
    cursor: pointer;
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
}
.flag-modal-reason input[type="radio"] { margin-top: 0.2rem; }
.flag-modal-notes {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    font-size: var(--text-sm);
}
.flag-modal-notes textarea {
    width: 100%;
    padding: var(--space-1) var(--space-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font: inherit;
    resize: vertical;
}
.flag-modal-actions {
    display: flex;
    gap: var(--space-2);
    align-items: center;
    margin-top: var(--space-1);
}

/* Confirmation pill that swaps in after a successful flag. Brief
 * fade-out so the disclosure can return to its normal state without
 * a jarring vanish. */
.flag-confirmation {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    color: var(--color-fg-muted);
    font-size: var(--text-sm);
    padding: var(--space-1) var(--space-2);
    margin: 0;
    animation: flag-confirmation-fade 4s ease forwards;
}
.flag-confirmation-icon {
    display: inline-flex;
    width: 1rem;
    height: 1rem;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    background: var(--color-success);
    color: var(--color-bg);
    font-size: var(--text-xs);
}
@keyframes flag-confirmation-fade {
    0%, 80% { opacity: 1; }
    100% { opacity: 0; visibility: hidden; }
}

/* Editor flags dashboard. Reuses the editor-* chrome from Phase 3.7's
 * editor surfaces; the table itself is the only new structural element.
 * No Sage moments — operator surface stays direct. */
.editor-flags-tabs {
    display: flex;
    gap: var(--space-2);
    margin: var(--space-3) 0;
    border-bottom: 1px solid var(--color-border);
}
.editor-flags-tab {
    padding: var(--space-2) var(--space-3);
    color: var(--color-fg-muted);
    text-decoration: none;
    border-bottom: 2px solid transparent;
    transition: color var(--duration-fast) var(--easing), border-color var(--duration-fast) var(--easing);
}
.editor-flags-tab:hover { color: var(--color-fg); }
.editor-flags-tab.is-active {
    color: var(--color-fg);
    border-bottom-color: var(--color-brand-yellow);
    font-weight: var(--weight-semibold);
}
.editor-flags-count {
    display: inline-block;
    background: var(--color-bg-sunken);
    color: var(--color-fg-muted);
    border-radius: var(--radius-pill);
    padding: 0.05rem 0.45rem;
    margin-left: var(--space-1);
    font-size: var(--text-xs);
}
.editor-flags-tab.is-active .editor-flags-count {
    background: var(--color-brand-yellow);
    color: var(--color-fg);
}

.editor-flags-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
}
.editor-flags-table th,
.editor-flags-table td {
    padding: var(--space-2) var(--space-3);
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--color-border);
}
.editor-flags-table th {
    font-weight: var(--weight-semibold);
    color: var(--color-fg-muted);
    background: var(--color-bg-sunken);
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
}
.editor-flags-table tbody tr:hover { background: var(--color-bg-cream); }
.editor-flags-record-uri,
.editor-flags-did {
    display: block;
    font-size: var(--text-xs);
    color: var(--color-fg-faint);
    word-break: break-all;
    max-width: 16rem;
}
.editor-flags-record-link {
    display: inline-block;
    margin-bottom: 0.15rem;
    font-size: var(--text-sm);
}
.editor-flags-reason {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    border-radius: var(--radius-sm);
    background: var(--color-bg-sunken);
    font-size: var(--text-xs);
}
/* Reason badges intentionally graduate by intensity: spam (mild) up to
 * harassment (strong) lift the danger tint progressively; misinformation
 * lands on the warning amber so it reads as a different category at a
 * glance. */
.editor-flags-reason-spam            { background: color-mix(in oklab, var(--color-danger) 10%, transparent); }
.editor-flags-reason-harassment      { background: color-mix(in oklab, var(--color-danger) 18%, transparent); }
.editor-flags-reason-misinformation  { background: color-mix(in oklab, var(--color-warning) 14%, transparent); }
.editor-flags-reason-inappropriate   { background: color-mix(in oklab, var(--color-danger) 14%, transparent); }
.editor-flags-reason-other           { background: var(--color-bg-sunken); }
.editor-flags-anon {
    color: var(--color-fg-muted);
    font-style: italic;
    font-size: var(--text-sm);
}
.editor-flags-notes summary {
    cursor: pointer;
    font-size: var(--text-sm);
    color: var(--color-fg);
}
.editor-flags-notes p {
    margin: var(--space-1) 0 0;
    font-size: var(--text-sm);
    color: var(--color-fg-muted);
    max-width: 32rem;
}
.editor-flags-empty { color: var(--color-fg-faint); }
.editor-flags-actions {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    align-items: flex-start;
}
.editor-flags-actions-col { white-space: nowrap; }
.editor-flags-action-form { margin: 0; }
.editor-flags-btn-hide,
.editor-flags-btn-dismiss,
.editor-flags-btn-unhide {
    font-size: var(--text-xs);
    padding: 0.2rem 0.6rem;
}
.editor-flags-resolution {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    border-radius: var(--radius-sm);
    font-size: var(--text-xs);
}
.editor-flags-resolution-hidden    { background: color-mix(in oklab, var(--color-danger) 12%, transparent); }
.editor-flags-resolution-dismissed { background: var(--color-bg-sunken); color: var(--color-fg-muted); }

@media (max-width: 50rem) {
    .editor-flags-table thead { display: none; }
    .editor-flags-table tbody tr {
        display: grid;
        grid-template-columns: 1fr;
        gap: var(--space-1);
        padding: var(--space-2) 0;
    }
    .editor-flags-table td {
        border-bottom: 0;
        padding: var(--space-1) 0;
    }
    .editor-flags-table tbody tr + tr {
        border-top: 1px solid var(--color-border);
    }
}

/* ─── Print ─────────────────────────────────────────────────── */

@media print {
    .site-header, .site-footer, .skip-link, .record-actions, .form-actions { display: none; }
    body { background: white; color: black; }
    .site-main { padding: 0; max-width: none; }
    a { color: inherit; text-decoration: underline; }
}
