/* Organization admin panel shell.
 * Application-console layout (org bar + side nav + one content region),
 * deliberately not the "column of stacked contact-form-card glass blocks"
 * shape used by every other authenticated page on this site — see
 * docs/superpowers/specs/2026-07-31-org-admin-panel-design.md section 4.1.
 * Every colour, radius and font here is one of the custom properties
 * already declared in styles.css. This is a new layout, not a new brand.
 */

.org-admin { max-width: var(--container-width); margin: 0 auto; padding: 1.5rem 1rem 4rem; }

.oa-bar {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    background: var(--glass-bg); border: 1px solid var(--glass-border);
    border-radius: var(--border-radius); padding: 0.75rem 1rem; margin-bottom: 1rem;
}
.oa-bar-left { display: flex; align-items: center; gap: 0.75rem; min-width: 0; }
/* Always-present ground truth for "which organization is this". The
   <select> next to it is only shown when the caller administers more than
   one org (main.js sets its `hidden` attribute); this text is what a
   single-org admin sees instead of an empty strip, and what tells a
   multi-org admin the select's current value without reading the dropdown.
   No `display` override, same reasoning as #oa-seats/#oa-plan-badge below. */
.oa-org-name {
    font-weight: 600; color: var(--text-main); font-size: 0.95rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.oa-plan-badge {
    font-size: 0.75rem; padding: 0.2rem 0.6rem; border-radius: var(--border-radius-sm);
    background: rgba(16, 185, 129, 0.12); color: var(--success); white-space: nowrap;
}
/* Unlike every other <select> in the panel (.oa-policy-filter, .oa-field-mode,
   .oa-member-role select, ...), this one shipped with no CSS at all -- it
   rendered as a bare native control. A bare <select>'s native chrome
   follows `color-scheme`; en/styles.css now pins that to `light`, but the
   control still inherits none of the panel's own surface colours, so it
   reads as a foreign element next to its siblings.
   Every other select avoids this by being fully custom-styled
   (`appearance: none` + explicit colors); this one gets the same treatment,
   copied from .oa-policy-filter/.oa-field-mode below (same chevron, same
   themed option-list fix -- see that rule's own comment for why the option
   background/color exists at all). */
.oa-org-select {
    background: rgba(255, 255, 255, 0.04); border: 1px solid var(--glass-border);
    border-radius: var(--border-radius-sm); color: var(--text-main);
    font-family: var(--font-body); font-size: 0.9rem; padding: 0.45rem 0.7rem;
    outline: none; appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 0.6rem center; padding-right: 1.9rem;
}
.oa-org-select:focus { border-color: var(--accent-primary); box-shadow: 0 0 0 3px rgba(74, 90, 156, 0.15); }
.oa-org-select option { background: var(--bg-alt); color: var(--text-main); }
html[data-theme="light"] .oa-org-select { background: #ffffff; border-color: rgba(0, 0, 0, 0.14); }
.oa-seats { font-size: 0.85rem; color: var(--text-muted); white-space: nowrap; }
/* Holds the seat count at the bar's trailing edge without disturbing
   .oa-bar-left (org name / select / plan badge) or .oa-bar's own
   space-between split. */
.oa-bar-right { display: flex; align-items: center; gap: 0.75rem; flex-shrink: 0; }

/* --success/--warning/--danger (en/styles.css :root) get no
   :root[data-theme="light"] override -- unlike --text-main/--glass-bg/etc.
   they were chosen to read as bright text on a near-black background. Measured in a real
   browser against the panel's light-theme card background (see
   .superpowers/sdd/panel-light-theme-report.md): .oa-plan-badge's success
   green fell to ~2.1:1, well under the 4.5:1 WCAG AA floor for body text --
   the light card is close enough to white that the same green that pops on
   near-black nearly disappears on it. Every other panel rule that uses one
   of these three variables as a TEXT color (not a border, not the low-alpha
   background tint, both of which stay legible either way) has the same
   defect and gets the same fix below, at that rule's own section rather
   than listed here.
   The fix is a panel-local darker shade for light mode, NOT a change to
   --success/--warning/--danger themselves: those three are used as text
   color in a dozen places across en/styles.css outside this panel, all
   presumably already shipped and verified in light mode -- retuning the
   shared tokens to fix this panel would risk regressing every one of them
   for a problem that is local to this file. */
html[data-theme="light"] .oa-plan-badge { color: #065f46; }

/* Two columns on desktop, stacked below 860px. minmax(0, 1fr) rather than 1fr:
   a 1fr column takes min-width: auto, so a long host pattern or a wide table
   would push the content column past the grid instead of scrolling inside it. */
.oa-body { display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 1rem; }
@media (max-width: 860px) { .oa-body { grid-template-columns: minmax(0, 1fr); } }

/* main.js hides this element by setting the `hidden` attribute (no
   organizations to administer, or boot() failed). The user-agent
   stylesheet's `[hidden] { display: none }` rule always loses to an author
   `display` declaration on the same element, regardless of selector
   specificity -- cascade origin is resolved before specificity. Since
   .oa-body sets `display: grid` above, it needs its own [hidden] override
   or the grid stays on screen underneath whatever replaced it. Same fix as
   `.nav-avatar[hidden]` in styles.css, same reason. Every element this page
   both hides by attribute AND gives a `display` value needs this pairing;
   .oa-state, #oa-org-select and #oa-plan-badge don't set `display` here, so
   they don't. */
.oa-body[hidden] { display: none !important; }

.oa-nav {
    display: flex; flex-direction: column; gap: 0.15rem; align-self: start;
    background: var(--glass-bg); border: 1px solid var(--glass-border);
    border-radius: var(--border-radius); padding: 0.5rem;
}
.oa-nav-item {
    padding: 0.55rem 0.75rem; border-radius: var(--border-radius-sm);
    color: var(--text-muted); text-decoration: none; font-size: 0.9rem;
}
.oa-nav-item:hover { color: var(--text-main); background: rgba(255, 255, 255, 0.04); }
.oa-nav-item.is-active { color: var(--text-main); background: rgba(74, 90, 156, 0.18); }
.oa-nav-sep { height: 1px; background: var(--glass-border); margin: 0.4rem 0.5rem; }
/* :hover's white-tint overlay above is a highlight meant for a dark card --
   a 4% white wash over the light theme's already near-white .oa-nav
   background (~rgb(246,248,252)) shifts every channel by ~1/255, i.e. no
   visible hover feedback at all. .is-active needs no matching override: its
   fixed-alpha blue tint composites to a pale lavender against either
   canvas, and its text is var(--text-main), so it stays legible in both
   without a rewrite (verified in a real browser at ~12.9:1 in light mode). */
html[data-theme="light"] .oa-nav-item:hover { background: rgba(0, 0, 0, 0.04); }

.oa-content {
    background: var(--glass-bg); border: 1px solid var(--glass-border);
    border-radius: var(--border-radius); padding: 1.25rem; min-height: 320px;
}
.oa-state { margin-top: 1rem; font-size: 0.9rem; color: var(--text-muted); }

/* --- Overview section ---------------------------------------------------
 * Landing screen: four independent cards (Members, Policy, Recent activity,
 * Subscription), each built from whichever one of the panel's three
 * existing calls backs it -- see overview.js's own module comment. No
 * element here is ever hidden via the `hidden` attribute (every card is
 * rebuilt from scratch on each render), so unlike several rules above this
 * block needs no [hidden]-vs-author-display override. */

.oa-overview-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
@media (max-width: 640px) { .oa-overview-grid { grid-template-columns: minmax(0, 1fr); } }

.oa-overview-card {
    display: flex; flex-direction: column; gap: 0.5rem;
    background: rgba(255, 255, 255, 0.02); border: 1px solid var(--glass-border);
    border-radius: var(--border-radius-sm); padding: 1rem 1.1rem;
}
.oa-overview-card-title {
    margin: 0 0 0.2rem; font-size: 0.95rem; font-weight: 600; color: var(--text-main);
    padding-bottom: 0.4rem; border-bottom: 1px solid var(--glass-border);
}
.oa-overview-card-body { display: flex; flex-direction: column; gap: 0.35rem; }
.oa-overview-stat { margin: 0; font-size: 1.05rem; font-weight: 600; color: var(--text-main); }
.oa-overview-substat { margin: 0; font-size: 0.85rem; color: var(--text-muted); }
.oa-overview-modes { margin: 0.2rem 0 0; font-size: 0.8rem; color: var(--text-muted); }
/* Same wording + link pattern as .oa-roster-error/.oa-invite-error above --
   no `display` override anywhere in this rule, so plain rendering (this
   card is rebuilt, never hidden-in-place) stays safe. */
.oa-overview-card-error { margin: 0; font-size: 0.88rem; color: var(--text-main); }
/* past_due must not read as a neutral word among "Active"/"Trial" -- reuses
   the same --warning custom property .oa-seats-full and .oa-policy-dirty
   already use for "needs your attention", not a new color. */
.oa-overview-attention { color: var(--warning); }

.oa-overview-activity-list { display: flex; flex-direction: column; gap: 0.5rem; }
.oa-overview-activity-row { display: flex; flex-direction: column; gap: 0.1rem; }
.oa-overview-activity-when { font-size: 0.75rem; color: var(--text-muted); }
.oa-overview-activity-what { font-size: 0.85rem; color: var(--text-main); }

/* "View full history" / "Manage seats" -- reuses the existing .btn/.btn-outline
   look rather than a plain inline link, since both are an intentional route to
   another section, not incidental body text. */
.oa-overview-more-link { align-self: flex-start; margin-top: 0.3rem; padding: 0.4rem 0.8rem; font-size: 0.8rem; }

html[data-theme="light"] .oa-overview-card { background: rgba(0, 0, 0, 0.015); }
/* Same --warning-as-text contrast defect as .oa-plan-badge above (see that
   rule's comment for the measurement and why this is a panel-local shade
   rather than a change to --warning itself). */
html[data-theme="light"] .oa-overview-attention { color: #92400e; }

/* Organization card's inline rename form -- owner/admin only, see
   overview.js's buildOrganizationCard(). Same input look as
   .oa-invite-form's email field below, scoped to this card's own class
   rather than reused directly since the two forms are otherwise unrelated. */
.oa-org-rename-form { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.2rem; }
.oa-org-rename-form input[type="text"] {
    flex: 1; min-width: 200px;
    background: rgba(255, 255, 255, 0.04); border: 1px solid var(--glass-border);
    border-radius: var(--border-radius-sm); color: var(--text-main); font-family: var(--font-body);
    font-size: 0.9rem; padding: 0.6rem 0.75rem; outline: none;
}
.oa-org-rename-form input[type="text"]:focus {
    border-color: var(--accent-primary); box-shadow: 0 0 0 3px rgba(74, 90, 156, 0.15);
}

html[data-theme="light"] .oa-org-rename-form input[type="text"] {
    background: #ffffff; border-color: rgba(0, 0, 0, 0.14);
}

/* --- Policy editor (Task 9) ------------------------------------------- */

.oa-policy-toolbar {
    display: flex; align-items: center; flex-wrap: wrap; gap: 0.75rem;
    margin-bottom: 1.25rem; padding-bottom: 1rem; border-bottom: 1px solid var(--glass-border);
}
.oa-policy-version { font-size: 0.85rem; color: var(--text-muted); }
.oa-policy-dirty { font-size: 0.85rem; color: var(--warning); font-weight: 500; }
/* First action button carries the push -- version/dirty/filter stay left,
   Discard + Save cluster at the trailing edge, wrapping together below the
   rest on a narrow viewport instead of the row breaking mid-cluster. */
.oa-policy-toolbar .btn-outline { margin-left: auto; }

.oa-policy-filter,
.oa-field-mode {
    background: rgba(255, 255, 255, 0.04); border: 1px solid var(--glass-border);
    border-radius: var(--border-radius-sm); color: var(--text-main);
    font-family: var(--font-body); font-size: 0.85rem; padding: 0.45rem 0.7rem;
    outline: none; appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 0.6rem center; padding-right: 1.9rem;
}
.oa-policy-filter:focus,
.oa-field-mode:focus { border-color: var(--accent-primary); box-shadow: 0 0 0 3px rgba(74, 90, 156, 0.15); }

/* The closed <select> above is themed, but a native <option>'s OPEN list is
   platform-rendered and ignores the select's own background/color -- on
   Windows/Chromium that renders near-white text on a near-white list
   (reported as "bardzo białe na czarnym tle" / illegible in the smoke test).
   `option` styling is limited and platform-dependent -- a custom dropdown
   widget is out of scope here -- but background-color + color on `option`
   itself IS honoured on Windows/Chromium, which is what actually needs
   fixing. Same fix `.form-group select option` already applies in
   en/styles.css; --bg-alt/--text-main already swap per theme there (see
   html[data-theme="light"] in en/styles.css), so this needs no separate
   light-theme override, same as that precedent. */
.oa-policy-filter option,
.oa-field-mode option {
    background: var(--bg-alt);
    color: var(--text-main);
}

/* No `display` override anywhere in this rule -- the banner stays default
   `block` so the plain `hidden` attribute keeps working (see the comment in
   policy-editor.js next to showBanner/showConflict for why the action
   button inside it is handled differently: appended only when shown, never
   hidden-in-place, because `.btn` DOES set `display` and would need the
   same [hidden] override .oa-body has above). */
.oa-policy-banner {
    margin-bottom: 1rem; padding: 0.85rem 1rem; border-radius: var(--border-radius-sm);
    background: rgba(239, 68, 68, 0.08); border-left: 3px solid var(--danger);
    color: var(--text-main); font-size: 0.9rem;
}
.oa-policy-banner .btn { margin-left: 0.75rem; margin-top: 0.35rem; }

.oa-policy-groups { display: flex; flex-direction: column; gap: 1.5rem; }

/* Group filtering toggles this class, never the `hidden` attribute -- .oa-group
   sets no `display` of its own, so `.oa-group.is-filtered { display: none; }`
   has no competing author rule to lose to and needs no !important. */
.oa-group.is-filtered { display: none; }
.oa-group-title {
    margin: 0 0 0.6rem; font-size: 0.95rem; font-weight: 600; color: var(--text-main);
    padding-bottom: 0.4rem; border-bottom: 1px solid var(--glass-border);
}
.oa-group-rows { display: flex; flex-direction: column; gap: 0.6rem; }

.oa-field {
    display: flex; flex-direction: column; gap: 0.6rem;
    background: rgba(255, 255, 255, 0.02); border: 1px solid var(--glass-border);
    border-radius: var(--border-radius-sm); padding: 0.85rem 1rem;
}
.oa-field.has-error { border-color: var(--danger); }
.oa-field-header { display: flex; align-items: center; flex-wrap: wrap; gap: 0.6rem; }
.oa-field-label { font-weight: 600; color: var(--text-main); font-size: 0.92rem; }
.oa-field-path { font-family: monospace; font-size: 0.78rem; color: var(--text-muted); opacity: 0.8; }
.oa-field-mode { margin-left: auto; }

.oa-field-value select,
.oa-field-value input,
.oa-field-value textarea {
    width: 100%; background: rgba(255, 255, 255, 0.04); border: 1px solid var(--glass-border);
    border-radius: var(--border-radius-sm); color: var(--text-main); font-family: var(--font-body);
    font-size: 0.9rem; padding: 0.6rem 0.75rem; outline: none;
}
.oa-field-value select:focus,
.oa-field-value input:focus,
.oa-field-value textarea:focus { border-color: var(--accent-primary); box-shadow: 0 0 0 3px rgba(74, 90, 156, 0.15); }
.oa-field-value textarea { resize: vertical; min-height: 90px; }
/* binaryFormats renders a <div> of checkbox <label>s -- the only value
   control shape that isn't a single select/input/textarea. */
.oa-field-value label {
    display: inline-flex; align-items: center; gap: 0.35rem;
    margin-right: 1rem; font-size: 0.85rem; color: var(--text-main);
}

.oa-field-error { font-size: 0.82rem; color: var(--danger); margin-top: -0.2rem; }

html[data-theme="light"] .oa-policy-filter,
html[data-theme="light"] .oa-field-mode,
html[data-theme="light"] .oa-field-value select,
html[data-theme="light"] .oa-field-value input,
html[data-theme="light"] .oa-field-value textarea {
    background: #ffffff; border-color: rgba(0, 0, 0, 0.14);
}
html[data-theme="light"] .oa-field { background: rgba(0, 0, 0, 0.015); }
/* Same --warning/--danger-as-text contrast defect as .oa-plan-badge above
   (see that rule's comment). .oa-policy-dirty measured ~2.0:1,
   .oa-field-error ~3.4:1 -- both under the 4.5:1 floor. */
html[data-theme="light"] .oa-policy-dirty { color: #92400e; }
html[data-theme="light"] .oa-field-error { color: #b91c1c; }

/* hostEntries control: individual rows instead of a textarea, matching the
   extension's own Settings page (field-controls.js's buildHostEntriesControl
   carries the full rationale, including why there is no "Active" toggle
   here). Row layout mirrors .oa-member-row below rather than introducing a
   third shape. */
.oa-host-entries { display: flex; flex-direction: column; gap: 0.6rem; }
.oa-host-rows { display: flex; flex-direction: column; gap: 0.6rem; }
.oa-host-row {
    display: flex; align-items: center; flex-wrap: wrap; gap: 0.6rem;
    background: rgba(255, 255, 255, 0.02); border: 1px solid var(--glass-border);
    border-radius: var(--border-radius-sm); padding: 0.7rem 0.9rem;
}
.oa-host-row.has-error { border-color: var(--danger); }
/* flex-basis (via the shorthand) governs sizing over `width`, so this does
   not need to fight .oa-field-value input's `width: 100%` above -- that
   rule only wins when flex-basis is auto/content. */
.oa-host-pattern { flex: 1 1 220px; min-width: 180px; }
.oa-host-options { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.oa-host-toggle {
    display: inline-flex; align-items: center; gap: 0.35rem;
    font-size: 0.85rem; color: var(--text-main); white-space: nowrap;
}
/* .oa-field-value's blanket `input { width: 100% }` rule above targets
   text/number/textarea controls; without this override a checkbox here
   would render as a full-width rectangle instead of its native box -- the
   same latent issue the binaryFormats checkboxes above already carry, just
   never triggered because those never sit inside a wrapping flex row. */
.oa-host-toggle input[type="checkbox"] { width: auto; }
.oa-host-error { flex-basis: 100%; font-size: 0.8rem; color: var(--danger); margin-top: -0.2rem; }
.oa-host-add { align-self: flex-start; }

html[data-theme="light"] .oa-host-row { background: rgba(0, 0, 0, 0.015); }
/* Same --danger-as-text contrast defect as .oa-plan-badge above (see that
   rule's comment); measured ~3.3:1. */
html[data-theme="light"] .oa-host-error { color: #b91c1c; }

/* --- Members section (Task 10) ----------------------------------------- */

.oa-seats.oa-seats-full { color: var(--warning); font-weight: 600; }

/* No `display` override -- plain `hidden` toggling stays safe, same
   reasoning as .oa-policy-banner above. */
.oa-roster-error {
    margin-bottom: 1rem; padding: 0.7rem 0.9rem; border-radius: var(--border-radius-sm);
    background: rgba(239, 68, 68, 0.08); border-left: 3px solid var(--danger);
    color: var(--text-main); font-size: 0.88rem;
}

.oa-member-list { display: flex; flex-direction: column; gap: 0.6rem; margin-bottom: 1.5rem; }
.oa-member-row {
    display: flex; align-items: center; flex-wrap: wrap; gap: 0.75rem;
    background: rgba(255, 255, 255, 0.02); border: 1px solid var(--glass-border);
    border-radius: var(--border-radius-sm); padding: 0.7rem 0.9rem;
}
.oa-member-info { display: flex; flex-direction: column; gap: 0.15rem; flex: 1; min-width: 180px; }
.oa-member-name { font-weight: 600; color: var(--text-main); font-size: 0.92rem; }
.oa-member-you { font-size: 0.78rem; color: var(--text-muted); margin-left: 0.35rem; font-weight: 400; }
.oa-member-sub { font-size: 0.78rem; color: var(--text-muted); }
.oa-member-role { display: flex; align-items: center; }
.oa-member-role-text { font-size: 0.85rem; color: var(--text-muted); padding: 0.45rem 0.2rem; }
.oa-member-role select {
    background: rgba(255, 255, 255, 0.04); border: 1px solid var(--glass-border);
    border-radius: var(--border-radius-sm); color: var(--text-main);
    font-family: var(--font-body); font-size: 0.85rem; padding: 0.45rem 0.7rem;
    outline: none; appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 0.6rem center; padding-right: 1.9rem;
}
.oa-member-role select:focus { border-color: var(--accent-primary); box-shadow: 0 0 0 3px rgba(74, 90, 156, 0.15); }
/* Same open-option-list fix as .oa-field-mode above -- see that rule's
   comment. */
.oa-member-role select option { background: var(--bg-alt); color: var(--text-main); }
.oa-member-actions { display: flex; align-items: center; }
.oa-remove-btn { padding: 0.4rem 0.8rem; font-size: 0.8rem; }
/* Wraps to its own line under the row's flex-wrap rather than squeezing
   between the role and action columns. No `display` override -- plain
   `hidden` toggling stays safe. */
.oa-member-error { flex-basis: 100%; font-size: 0.8rem; color: var(--danger); margin-top: -0.2rem; }

.oa-invite-section { border-top: 1px solid var(--glass-border); padding-top: 1.25rem; }
.oa-invite-capacity {
    font-size: 0.85rem; color: var(--warning); background: rgba(245, 158, 11, 0.08);
    border-left: 3px solid var(--warning); border-radius: var(--border-radius-sm);
    padding: 0.6rem 0.85rem; margin: 0 0 0.9rem;
}
.oa-invite-form { display: flex; align-items: center; flex-wrap: wrap; gap: 0.6rem; margin-bottom: 0.75rem; }
.oa-invite-form input[type="email"],
.oa-invite-form select {
    background: rgba(255, 255, 255, 0.04); border: 1px solid var(--glass-border);
    border-radius: var(--border-radius-sm); color: var(--text-main); font-family: var(--font-body);
    font-size: 0.9rem; padding: 0.6rem 0.75rem; outline: none;
}
.oa-invite-form input[type="email"] { flex: 1; min-width: 220px; }
.oa-invite-form input[type="email"]:focus,
.oa-invite-form select:focus { border-color: var(--accent-primary); box-shadow: 0 0 0 3px rgba(74, 90, 156, 0.15); }
/* Same open-option-list fix as .oa-field-mode above -- see that rule's
   comment. */
.oa-invite-form select option { background: var(--bg-alt); color: var(--text-main); }
/* No `display` override -- plain `hidden` toggling stays safe. */
.oa-invite-error { font-size: 0.85rem; color: var(--danger); margin-bottom: 0.75rem; }

.oa-invite-result {
    background: rgba(16, 185, 129, 0.08); border-left: 3px solid var(--success);
    border-radius: var(--border-radius-sm); padding: 0.85rem 1rem; margin-top: 0.5rem;
}
.oa-invite-result p { margin: 0 0 0.5rem; font-size: 0.88rem; color: var(--text-main); }
.oa-invite-result-row { display: flex; gap: 0.5rem; align-items: center; }
.oa-invite-result-row input {
    flex: 1; font-size: 0.78rem; padding: 0.45rem 0.65rem; background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--glass-border); border-radius: var(--border-radius-sm); color: var(--text-main);
    font-family: var(--font-body);
}

html[data-theme="light"] .oa-member-role select,
html[data-theme="light"] .oa-invite-form input[type="email"],
html[data-theme="light"] .oa-invite-form select,
html[data-theme="light"] .oa-invite-result-row input {
    background: #ffffff; border-color: rgba(0, 0, 0, 0.14);
}
html[data-theme="light"] .oa-member-row { background: rgba(0, 0, 0, 0.015); }
/* Same --warning/--danger-as-text contrast defect as .oa-plan-badge above
   (see that rule's comment). .oa-seats-full and .oa-invite-capacity share
   the --warning fix; .oa-member-error and .oa-invite-error share the
   --danger fix. */
html[data-theme="light"] .oa-seats.oa-seats-full,
html[data-theme="light"] .oa-invite-capacity {
    color: #92400e;
}
html[data-theme="light"] .oa-member-error,
html[data-theme="light"] .oa-invite-error {
    color: #b91c1c;
}

/* --- History section (Task 11) ------------------------------------------ */

.oa-history-list { display: flex; flex-direction: column; gap: 0.6rem; }
.oa-history-row {
    display: flex; flex-direction: column; gap: 0.25rem;
    background: rgba(255, 255, 255, 0.02); border: 1px solid var(--glass-border);
    border-radius: var(--border-radius-sm); padding: 0.7rem 0.9rem;
}
.oa-history-when { font-size: 0.78rem; color: var(--text-muted); }
.oa-history-what { font-size: 0.9rem; color: var(--text-main); }
.oa-history-empty { font-size: 0.9rem; color: var(--text-muted); }

.oa-history-detail { margin-top: 0.35rem; font-size: 0.82rem; color: var(--text-muted); }
.oa-history-detail summary { cursor: pointer; color: var(--text-main); font-weight: 500; }
.oa-history-detail-line { margin-top: 0.25rem; }

.oa-history-more { display: flex; align-items: center; gap: 0.75rem; margin-top: 1.25rem; }
/* No `display` override -- plain `hidden` toggling stays safe, same
   reasoning as .oa-roster-error/.oa-invite-error in the Members section
   above (this class carries no author `display` of its own). */
.oa-history-error { font-size: 0.85rem; color: var(--danger); }

html[data-theme="light"] .oa-history-row { background: rgba(0, 0, 0, 0.015); }
/* Same --danger-as-text contrast defect as .oa-plan-badge above (see that
   rule's comment); measured ~3.5:1. */
html[data-theme="light"] .oa-history-error { color: #b91c1c; }
