/* =============================================================
   AOP HUB, page-scoped styles.
   ─────────────────────────────────────────────────────────────
   The extension marketplace front page. Dark throughout in the
   AOP visual language (see styles/aop.css): every section sits
   on --color-dark-blue, teal is the page accent, shared
   primitives (.btn, .tile-glow, .tick-list, .eyebrow,
   .statement-headline, .headline-dot, .editorial-section-head)
   are reused.

   The hub is a self-contained sub-site: it uses its OWN chrome
   (components/aop-hub-header.html + aop-hub-footer.html) instead
   of the main site nav/footer. This stylesheet is shared by every
   aop-hub-* page; page-specific sections are marked as such.

   Sections (top to bottom):
     1. Page-level tokens + accent remap (blue → teal)
     2. Reveal primitive
     3. Hub header + footer (shared chrome)
     4. Hero (copy + floating extension constellation)
     5. Trending / New panels
     6. Directory (finder controls, results bar, cards, empty state)
     7. Dev Portal CTA band
     8. Detail pages, shared blocks (aoph-*)
     9. Extension detail page only (aophx-*)
    10. Developer profile only (aophd-*)
    11. Dev Portal dashboard only (aopha-*)

   PREFIXES
     aoph-   shared by more than one hub page (§1-8). Anything a
             second page could plausibly need lives here.
     aophx-  extension detail page only (§9).
     aophd-  developer profile only (§10).
     aopha-  Dev Portal dashboard, the signed-in account page (§11).
   ============================================================= */


/* ─────────────────────────────────────────────────────────────
   1. PAGE-LEVEL TOKENS
   The ^= prefix selector covers every hub page (aop-hub,
   aop-hub-extension, …). The blue→teal accent remap (focus ring,
   headline dots, accent tags, icon-tile wash, .btn--blue variants)
   is shared across the AOP family, see "AOP-SCOPED PAGES" in
   styles/components.css.
   ───────────────────────────────────────────────────────────── */
/* The AOP teal set (--aop-teal, --aop-teal-soft/-line/-faint/-tint,
   --aop-blue-soft) is global, see styles/tokens.css. */
body[data-page^="aop-hub"] {
  background: var(--color-dark-blue);
  color: var(--color-white);
}

body[data-page^="aop-hub"] section {
  background: var(--color-dark-blue);
  color: var(--color-white);
}

/* No hairlines between sections anywhere on the hub. Section rhythm
   comes from padding alone; the shared .cta-band carries a top rule on
   other pages, so it is switched off here too. */
body[data-page^="aop-hub"] .cta-band { border-top: 0; }

/* Dark pages: the shared .statement-headline defaults to dark-blue,
   repaint it white (mirrors aop.css / aop-developers.css). */
body[data-page^="aop-hub"] .statement-headline { color: var(--color-white); }

.aoph-eyebrow {
  color: var(--aop-teal);
  margin-bottom: var(--sp-24);
}

.aoph-h2 { max-width: 20ch; }


/* ═════════════════════════════════════════════════════════════════
   3. HUB HEADER + FOOTER, shared chrome for every aop-hub-* page.
   ═════════════════════════════════════════════════════════════════ */
.aoph-nav {
  background: var(--color-dark-blue);
  border-bottom: 1px solid var(--color-white-8);
}
.aoph-nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-16);
  min-height: var(--menu-height);
  padding-top: var(--sp-12);
  padding-bottom: var(--sp-12);
}
.aoph-nav-logo {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-12);
  text-decoration: none;
}
.aoph-nav-logo img {
  height: 30px;
  width: auto;
  display: block;
}
/* "Hub" beside the AOP mark: label typography, uppercase, with a
   short hairline as the divider so the lockup stays readable as
   two parts. Sized below the logo's cap height, it reads as the
   sub-brand, not as a second logo. */
.aoph-nav-logo-hub {
  padding-left: var(--sp-12);
  border-left: 1px solid var(--color-white-15);
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-15);
  letter-spacing: 1.5px;
  /* The line box doubles as the divider height: 24px next to the
     30px logo keeps the rule short of the mark's full height. */
  line-height: 24px;
  text-transform: uppercase;
  color: var(--color-white);
}
/* Login button: .btn--sm keeps the hub bar slim; .aoph-login-btn
   stays in the markup purely as the auth-toggle hook below. */

/* ── Account area (logged-in state) ── */
.aoph-nav-account {
  display: flex;
  align-items: center;
  gap: var(--sp-12);
}
/* js/aop-hub-auth.js toggles auth states via the hidden attribute;
   these rules make it beat the display declarations below (and the
   .btn base's inline-flex), same pattern as the other finder pages. */
.aoph-login-btn[hidden],
.aoph-user-wrap[hidden],
.aoph-user-menu[hidden],
[data-aoph-auth-show][hidden] { display: none; }

/* The chip is the menu trigger; the panel is positioned against
   this wrapper. */
.aoph-user-wrap { position: relative; }
.aoph-user {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  padding: 5px 12px 5px 5px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-white-15);
  background: var(--color-white-5);
  color: var(--color-white);
  cursor: pointer;
  transition: border-color var(--duration-xs) var(--ease-smooth);
}
@media (hover: hover) and (pointer: fine) {
  .aoph-user:hover { border-color: var(--aop-teal-line); }
}
.aoph-user:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 2px;
}
.aoph-user-chevron {
  width: 14px;
  height: 14px;
  color: var(--color-white-70);
  transition: transform var(--duration-xs) var(--ease-smooth);
}
.aoph-user[aria-expanded="true"] .aoph-user-chevron { transform: rotate(180deg); }
.aoph-user-avatar {
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-circle);
  background: var(--aop-teal-soft);
  color: var(--aop-teal);
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-12);
  letter-spacing: 0.5px;
}
.aoph-user-name {
  font-family: var(--font-heading);
  font-weight: var(--fw-button);
  font-size: var(--text-14);
  color: var(--color-white);
  white-space: nowrap;
}
/* ── Account menu ──
   Disclosure panel under the chip. Open/close, Esc and outside
   clicks are handled by js/aop-hub-auth.js. */
.aoph-user-menu {
  position: absolute;
  top: calc(100% + var(--sp-8));
  right: 0;
  z-index: 30;
  min-width: 260px;
  padding: var(--sp-8);
  border: 1px solid var(--color-white-15);
  border-radius: var(--radius-md);
  background: var(--color-dark-blue);
  box-shadow: var(--shadow-tile-hover);
  animation: aoph-menu-in var(--duration-xs) var(--ease-smooth);
}
@keyframes aoph-menu-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .aoph-user-menu { animation: none; }
}
.aoph-user-menu-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--sp-12) var(--sp-12) var(--sp-16);
  margin: 0;
  border-bottom: 1px solid var(--color-white-8);
}
.aoph-user-menu-name {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-14);
  color: var(--color-white);
}
.aoph-user-menu-org {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-12);
  color: var(--color-white-70);
}
.aoph-user-menu-list {
  list-style: none;
  margin: 0;
  padding: var(--sp-8) 0 0 0;
}
.aoph-user-menu-list--foot {
  margin-top: var(--sp-8);
  border-top: 1px solid var(--color-white-8);
}
.aoph-user-menu-list a,
.aoph-user-menu-list button {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--sp-12);
  padding: var(--sp-12);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-white-85);
  font-family: var(--font-heading);
  font-weight: var(--fw-button);
  font-size: var(--text-14);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--duration-xs) var(--ease-smooth),
              color var(--duration-xs) var(--ease-smooth);
}
.aoph-user-menu-list svg {
  width: var(--icon-sm);
  height: var(--icon-sm);
  flex-shrink: 0;
  color: var(--aop-teal);
}
@media (hover: hover) and (pointer: fine) {
  .aoph-user-menu-list a:hover,
  .aoph-user-menu-list button:hover {
    background: var(--color-white-5);
    color: var(--color-white);
  }
}
.aoph-user-menu-list a:focus-visible,
.aoph-user-menu-list button:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: -2px;
}

@media (max-width: 639px) {
  /* Keep the bar slim on phones, initials + chevron only. */
  .aoph-user { padding: 5px 8px 5px 5px; }
  .aoph-user-name { display: none; }
  .aoph-user-menu { min-width: min(78vw, 260px); }
}

/* ── Auth modal (registration/login simulation) ──
   Native <dialog>; showModal() centers it and contains focus. */
.aoph-auth-modal {
  width: min(92vw, 440px);
  border: none;
  padding: 0;
  background: transparent;
  color: var(--color-white);
}
.aoph-auth-modal::backdrop {
  /* Literal color: custom properties are not reliably resolved on
     ::backdrop across engines. Mirrors --color-dark-blue at ~65%.
     Keep in sync with .aophx-sbom-modal::backdrop below. */
  background: rgba(10, 16, 29, 0.65);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
}
.aoph-auth-modal[open] {
  animation: aoph-modal-in var(--duration-base) var(--ease-smooth);
}
@keyframes aoph-modal-in {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .aoph-auth-modal[open] { animation: none; }
}
/* ── Modal card shell ──
   Shared by the three hub dialog cards (auth, extension lock, SBOM
   viewer): dark gradient tile, white-15 hairline, large radius,
   clamp padding. Hub-specific chrome, so it lives here and not in
   components.css. Consumers compose it in the markup and keep only
   genuine deltas on their own class. */
.aoph-modal-card {
  position: relative;
  background: var(--gradient-tile-dark);
  border: 1px solid var(--color-white-15);
  border-radius: var(--radius-lg);
  padding: clamp(var(--sp-24), 5vw, var(--sp-40));
}

.aoph-auth-card {
  max-height: 85vh;
  overflow: auto;
}
.aoph-auth-close {
  position: absolute;
  top: var(--sp-16);
  right: var(--sp-16);
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-circle);
  border: 1px solid transparent;
  background: transparent;
  color: var(--color-white-70);
  cursor: pointer;
  transition: color var(--duration-xs) var(--ease-smooth),
              border-color var(--duration-xs) var(--ease-smooth);
}
.aoph-auth-close svg { width: var(--icon-sm); height: var(--icon-sm); }
@media (hover: hover) and (pointer: fine) {
  .aoph-auth-close:hover { color: var(--color-white); border-color: var(--color-white-15); }
}
.aoph-auth-close:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 2px;
}
.aoph-auth-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-heading);
  font-size: var(--text-h3-lg);
  letter-spacing: -0.01em;
  line-height: 1.2; /* one-off */
  color: var(--color-white);
  margin: 0 var(--sp-32) var(--sp-12) 0;
}
.aoph-auth-sub {
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-14);
  line-height: 1.55;
  color: var(--color-white-70);
  margin: 0 0 var(--sp-24) 0;
}
.aoph-auth-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-16);
}
.aoph-field--wide { grid-column: 1 / -1; }
.aoph-field {
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
}
.aoph-field-label {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-12);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--aop-teal);
}
/* Field inputs: the shared .input--dark primitive (components.css),
   composed in the markup. No hub-specific deltas. */
.aoph-auth-submit {
  width: 100%;
  justify-content: center;
  margin-top: var(--sp-24);
}

/* T&C-Zustimmung vor der Kontoanfrage (Vorgabe Advancis 31.08.). */
.aoph-terms {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-8);
  margin-top: var(--sp-16);
  cursor: pointer;
}
.aoph-terms input[type="checkbox"] {
  width: 16px;
  height: 16px;
  margin: 2px 0 0;
  flex-shrink: 0;
  cursor: pointer;
  accent-color: var(--aop-teal);
}
.aoph-terms-text {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  line-height: 1.5;
  color: var(--color-white-70);
}
.aoph-terms-text a {
  color: var(--color-white);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.aoph-terms-text a:hover { color: var(--aop-teal); }
.aoph-terms:focus-within {
  outline: 2px solid var(--aop-teal);
  outline-offset: 3px;
  border-radius: var(--radius-sm, 4px);
}
.aoph-auth-note {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-12);
  color: var(--color-white-70);
  text-align: center;
  margin: var(--sp-16) 0 0 0;
}
@media (max-width: 480px) {
  .aoph-auth-grid { grid-template-columns: 1fr; }
}

.aoph-footer {
  background: var(--color-dark-blue);
  border-top: 1px solid var(--color-white-8);
  color: var(--color-white);
}
.aoph-footer-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: clamp(var(--sp-32), 5vw, var(--sp-96));
  padding-top: clamp(var(--sp-40), 6vw, var(--sp-64));
  padding-bottom: clamp(var(--sp-40), 6vw, var(--sp-64));
}
.aoph-footer-brand img { height: 28px; width: auto; display: block; }
.aoph-footer-tagline {
  margin: var(--sp-20) 0 0 0;
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-body);
  line-height: var(--lh-body-ratio);
  color: var(--color-white-70);
  max-width: 44ch;
}
.aoph-footer-heading {
  display: block;
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-12);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--aop-teal);
  margin-bottom: var(--sp-16);
}
.aoph-footer-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-12);
}
.aoph-footer-nav a {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white-70);
  text-decoration: none;
  transition: color var(--duration-xs) var(--ease-smooth);
}
@media (hover: hover) and (pointer: fine) {
  .aoph-footer-nav a:hover { color: var(--color-white); }
}
.aoph-footer-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-12) var(--sp-24);
  padding-top: var(--sp-20);
  padding-bottom: var(--sp-20);
  border-top: 1px solid var(--color-white-8);
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-12);
  color: var(--color-white-70);
}
.aoph-footer-legal {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-20);
}
.aoph-footer-legal a {
  color: var(--color-white-70);
  text-decoration: none;
  transition: color var(--duration-xs) var(--ease-smooth);
}
@media (hover: hover) and (pointer: fine) {
  .aoph-footer-legal a:hover { color: var(--color-white); }
}
@media (max-width: 639px) {
  .aoph-footer-inner { grid-template-columns: 1fr; gap: var(--sp-32); }
}


/* ═════════════════════════════════════════════════════════════════
   4. HERO
   ═════════════════════════════════════════════════════════════════ */
.aoph-hero {
  position: relative;
  isolation: isolate;
  background: var(--color-dark-blue);
  color: var(--color-white);
  padding-top: var(--sp-section-md);
  padding-bottom: var(--sp-section-md);
  overflow: hidden;
}
/* Quiet, centered teal glow behind the headline + search. */
.aoph-hero-aurora {
  position: absolute;
  top: -35%;
  left: 50%;
  transform: translateX(-50%);
  width: 80%;
  height: 90%;
  background: var(--glow-radial-teal);
  filter: blur(40px);
  pointer-events: none;
  z-index: 0;
}
.aoph-hero-inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.aoph-hero-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-heading);
  font-size: var(--text-hero);
  line-height: var(--lh-tight);
  letter-spacing: -0.02em;
  color: var(--color-white);
  margin: 0;
  max-width: 24ch;
}
.aoph-hero-lede {
  margin: var(--sp-24) 0 0 0;
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-lead);
  line-height: var(--lh-body-ratio);
  color: var(--color-white-70);
  max-width: 56ch;
}

/* ── Hero search ──
   One prominent pill: icon + input + submit button. Submits into
   the directory search below (js/aop-hub.js). */
.aoph-hero-search {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
  max-width: 640px;
  margin-top: clamp(var(--sp-32), 4vw, var(--sp-40));
  padding: 6px 6px 6px 0;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-white-15);
  background: var(--color-white-5);
  transition: border-color var(--duration-xs) var(--ease-smooth),
              background var(--duration-xs) var(--ease-smooth);
}
.aoph-hero-search:focus-within {
  border-color: var(--aop-teal);
  background: var(--aop-teal-faint);
}
.aoph-hero-search-icon {
  flex-shrink: 0;
  width: var(--icon-md);
  height: var(--icon-md);
  margin-left: var(--sp-24);
  color: var(--color-white-70);
  pointer-events: none;
}
.aoph-hero-search input {
  flex: 1;
  min-width: 0;
  padding: 12px var(--sp-16);
  border: none;
  background: transparent;
  color: var(--color-white);
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-16);
}
.aoph-hero-search input::placeholder { color: var(--color-white-70); opacity: 0.6; }
.aoph-hero-search input:focus { outline: none; }
/* Slightly tighter pill so it nests inside the search bar. */
.aoph-hero-search-btn { padding: 11px var(--sp-24); }

/* ── Hub chip, dark-surface toggle (company-page tabs) ── */
.aoph-chip {
  /* Layers on .chip (pill radius, 44px tap floor, transitions);
     this keeps only the hub scale + dark-surface colors. */
  padding: 7px var(--sp-16);
  font-size: var(--text-14);
  border-color: var(--color-white-15);
  color: var(--color-white-70);
}
@media (hover: hover) and (pointer: fine) {
  .aoph-chip:hover {
    border-color: var(--aop-teal-line);
    background: var(--aop-teal-faint);
    color: var(--color-white);
  }
}
.aoph-chip:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 2px;
}
/* Active state for the shared hub chip. Added for the company page's
   tabs; any future hub toggle can use it. */
.aoph-chip.is-active {
  border-color: var(--aop-teal-line);
  background: var(--aop-teal-faint);
  color: var(--color-white);
}

.aoph-hero-stats {
  margin: var(--sp-32) 0 0 0;
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-12);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--color-white-70);
}
.aoph-hero-stats strong {
  color: var(--aop-teal);
  font-weight: var(--fw-label);
}

@media (max-width: 639px) {
  /* Stack the submit button under the input on small screens. */
  .aoph-hero-search {
    flex-wrap: wrap;
    padding: 6px;
    border-radius: var(--radius-lg);
  }
  .aoph-hero-search-icon { margin-left: var(--sp-16); }
  .aoph-hero-search input { flex: 1 1 60%; }
  .aoph-hero-search-btn { flex: 1 1 100%; justify-content: center; }
}


/* ═════════════════════════════════════════════════════════════════
   5. TRENDING / NEW PANELS (start page)
   App-store-style chart lists: flat quiet surface (no glow), rows
   with rank, app-icon tile, name + "publisher · type", and a View
   affordance with a metric caption underneath.
   ═════════════════════════════════════════════════════════════════ */
.aoph-picks {
  padding: var(--sp-section-sm) 0;
}
.aoph-picks-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-24);
  align-items: start;
}
@media (max-width: 1023px) { .aoph-picks-grid { grid-template-columns: 1fr; } }

/* Shell comes from .surface-quiet --faint (components.css); the
   panel keeps its asymmetric padding. */
.aoph-panel {
  --surface-quiet-pad: clamp(var(--sp-20), 2vw, var(--sp-24)) clamp(var(--sp-20), 2vw, var(--sp-32));
}
.aoph-panel-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-16);
  padding-bottom: var(--sp-16);
}
.aoph-panel-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-h3);
  color: var(--color-white);
  margin: 0;
  line-height: 1.2; /* one-off */
}
.aoph-panel-sub {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white-70);
  margin: 4px 0 0 0;
}
/* "See all" link: .arrow-link (components.css) carries type, slide
   and focus ring (teal via the hub's --btn-focus-ring remap). */
.aoph-panel-more {
  margin-top: 4px;
  color: var(--aop-teal);
  white-space: nowrap;
}

.aoph-panel-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.aoph-panel-row { border-top: 1px solid var(--color-white-8); }
.aoph-panel-row a {
  display: grid;
  grid-template-columns: 28px 48px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-16);
  padding: var(--sp-16) var(--sp-8);
  text-decoration: none;
  transition: background var(--duration-xs) var(--ease-smooth);
}
/* The New panel has no rank column. */
.aoph-panel--new .aoph-panel-row a { grid-template-columns: 48px minmax(0, 1fr) auto; }
@media (hover: hover) and (pointer: fine) {
  .aoph-panel-row a:hover { background: var(--color-white-5); }
}
.aoph-panel-rank {
  font-family: var(--font-heading);
  font-weight: var(--fw-light);
  font-size: var(--text-h3);
  color: var(--color-white-70);
  text-align: center;
}
/* App-icon tile: .icon-tile .icon-tile--48 (48px, teal wash via the
   page rule at the top); the class stays as the hook for the
   mobile shrink below. Normalized from a one-off 44px / 10px-radius
   tile to the shared 48px / --radius-sm register. */

.aoph-panel-ext { min-width: 0; }
.aoph-panel-ext-name {
  display: block;
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-16);
  color: var(--color-white);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.aoph-panel-ext-sub {
  display: block;
  margin-top: 2px;
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-12);
  color: var(--color-white-70);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Right-hand metric column ("66 sold this season" / publish date). */
.aoph-panel-caption {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-12);
  color: var(--color-white-70);
  white-space: nowrap;
  text-align: right;
}
@media (max-width: 639px) {
  /* The metric moves under the name column so names keep their
     full width on narrow screens. */
  .aoph-panel-row a { grid-template-columns: 24px 40px minmax(0, 1fr); gap: 2px var(--sp-12); }
  .aoph-panel--new .aoph-panel-row a { grid-template-columns: 40px minmax(0, 1fr); }
  .aoph-panel-app-icon { width: 40px; height: 40px; }
  .aoph-panel-caption {
    grid-column: 3;
    justify-self: start;
    text-align: left;
    font-size: var(--text-11);
  }
  .aoph-panel--new .aoph-panel-caption { grid-column: 2; }
}


/* ═════════════════════════════════════════════════════════════════
   5b. REGISTER CTA (start page)
   Compact promo banner between the chart panels and the directory:
   teal-washed card, copy left, account CTAs right.
   ═════════════════════════════════════════════════════════════════ */
.aoph-register {
  padding: var(--sp-section-sm) 0;
}
.aoph-register-card {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) auto;
  align-items: center;
  gap: clamp(var(--sp-24), 4vw, var(--sp-64));
  padding: clamp(var(--sp-32), 4vw, var(--sp-48));
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-white-15);
  background: linear-gradient(120deg, var(--aop-teal-soft), transparent 55%), var(--color-white-2);
}
.aoph-register-card .aoph-eyebrow {
  display: inline-block;
  margin-bottom: var(--sp-12);
}
.aoph-register-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-heading);
  font-size: var(--text-h3-lg);
  letter-spacing: -0.01em;
  line-height: 1.2; /* one-off */
  color: var(--color-white);
  margin: 0 0 var(--sp-12) 0;
}
.aoph-register-body {
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-body);
  line-height: var(--lh-body-ratio);
  color: var(--color-white-70);
  margin: 0;
  max-width: 56ch;
}
.aoph-register-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-16);
}
@media (max-width: 1023px) {
  .aoph-register-card { grid-template-columns: 1fr; }
}


/* ═════════════════════════════════════════════════════════════════
   6. DIRECTORY (start page)
   ═════════════════════════════════════════════════════════════════ */
.aoph-directory {
  padding: var(--sp-section-md) 0;
}
.aoph-dir-lede { max-width: 48ch; }

/* ── Finder controls ──
   Composes the shared .finder primitive with the .finder--on-dark
   modifier (components.css), the dark counterpart of the
   technology-partner finder controls. The page keeps only the
   column layout: search (wide) + four selects + reset on one
   wrapping grid row. */
.aoph-controls {
  grid-template-columns: minmax(240px, 1.5fr) repeat(4, minmax(150px, 1fr)) auto;
}
@media (max-width: 1280px) {
  .aoph-controls { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .aoph-controls .finder-search { grid-column: 1 / -1; }
}
@media (max-width: 639px) {
  .aoph-controls { grid-template-columns: 1fr 1fr; }
}

/* ── Results bar: live count left, view toggle right ── */
.aoph-results-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-16);
  margin: var(--sp-32) 0 var(--sp-24);
}
.aoph-count {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-12);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--color-white-70);
  margin: 0;
}
.aoph-count #aoph-count-num { color: var(--aop-teal); }

.aoph-view {
  display: inline-flex;
  padding: 3px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-white-15);
  background: var(--color-white-5);
}
.aoph-view-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 32px;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--color-white-70);
  cursor: pointer;
  transition: background var(--duration-xs) var(--ease-smooth),
              color var(--duration-xs) var(--ease-smooth);
}
.aoph-view-btn svg { width: var(--icon-sm); height: var(--icon-sm); }
.aoph-view-btn.is-active {
  background: var(--aop-teal-soft);
  color: var(--aop-teal);
}
@media (hover: hover) and (pointer: fine) {
  .aoph-view-btn:not(.is-active):hover { color: var(--color-white); }
}
.aoph-view-btn:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 2px;
}

/* ── Results grid / list ── */
.aoph-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-20); /* card-register grids use --sp-20 site-wide */
}
@media (max-width: 1023px) { .aoph-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 639px)  { .aoph-grid { grid-template-columns: 1fr; } }

.aoph-card.is-hidden { display: none; }

/* Shell, teal hover and focus ring come from the .surface-quiet
   --faint --interactive composition (set by js/aop-hub.js on the
   rendered card link); this class keeps only the card's layout. */
.aoph-card-link {
  display: flex;
  flex-direction: column;
  gap: var(--sp-12);
  height: 100%;
  text-decoration: none;
}
@media (hover: hover) and (pointer: fine) {
  /* Whole card is the trigger, so the consumer drives the arrow-link slide. */
  .aoph-card-link:hover .aoph-card-cta svg { transform: translateX(var(--btn-icon-shift)); }
}

/* Top row: icon left, badges pinned to the top-right corner. */
.aoph-card-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-12);
}
/* Card icon: .icon-tile .icon-tile--48 (48px, teal wash via the
   page rule at the top); the class stays as the hook for the list
   view + the card's slightly larger 24px glyph. */
.aoph-card-icon svg { width: 24px; height: 24px; }

/* ── Corner badges: [Featured by Advancis] [status] ──
   The developer-status pill always sits in the top-right corner;
   the featured marker goes beside it. */
.aoph-card-badges {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--sp-8);
}
/* The badges themselves are the shared .tag primitive (components.css):
   the scope marker renders as `tag tag--on-dark`, the featured marker
   as `tag aoph-tag--featured` (both JS-generated, js/aop-hub.js). */
/* Developer-status tier dot. Tier colors are data semantics
   (Blue / Silver / Gold program levels), not decorative accents.
   Used both inside the detail-page status pill and inline after the
   developer name on directory cards (--inline). */
.aoph-status-dot {
  width: 7px;
  height: 7px;
  border-radius: var(--radius-circle);
  background: var(--color-white-70);
}
.aoph-status-dot--inline {
  display: inline-block;
  margin-left: 7px;
  vertical-align: middle;
}
/* The .aoph-tag--status-* classes are JS-generated (aop-hub.js,
   aop-hub-extension.js) and only pick the tier color of the dot
   inside a status tag / inline status label. Silver/gold use the
   cross-page tier accents (tokens.css) — never AIM orange. */
.aoph-tag--status-blue   .aoph-status-dot,
.aoph-status-dot--blue   { background: var(--color-blue); }
.aoph-tag--status-silver .aoph-status-dot,
.aoph-status-dot--silver { background: var(--tier-silver); }
.aoph-tag--status-gold   .aoph-status-dot,
.aoph-status-dot--gold   { background: var(--tier-gold); }
/* "Featured", editorial pick. Tag color variant (JS-generated,
   composes the .tag primitive): solid teal with a teal glow and
   dark label so it visibly pops against the dark cards. */
.aoph-tag--featured {
  --tag-bg:    var(--color-teal);
  --tag-color: var(--color-dark-blue);
  box-shadow: 0 0 14px var(--accent-line-aop);
}

.aoph-card-name {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-h3);
  line-height: var(--lh-heading);
  color: var(--color-white);
  margin: var(--sp-4) 0 0 0;
}
.aoph-card-pub {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white-70);
  margin: 0;
}
.aoph-card-summary {
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-14);
  line-height: 1.5;
  color: var(--color-white-70);
  margin: 0;
}

/* Tag list on the extension detail page. Layout only — each <li>
   is a shared .tag (JS-generated, js/aop-hub-extension.js):
   scope = `tag tag--accent`, status = `tag tag--on-dark
   aoph-tag--status-*`, featured = `tag aoph-tag--featured`. */
.aoph-card-tags {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-8);
}

/* Footer row: sales metrics left, arrow affordance right. */
.aoph-card-foot {
  margin-top: auto;
  padding-top: var(--sp-16);
  border-top: 1px solid var(--color-white-8);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-12);
}
.aoph-card-sales {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-12);
  color: var(--color-white-70);
}
.aoph-card-sales strong {
  font-weight: var(--fw-subheading);
  font-family: var(--font-heading);
  color: var(--color-white);
}
/* Corner arrow: icon-only .arrow-link; the slide comes from the
   whole-card hover rule above (arrow-link consumer pattern). */
.aoph-card-cta { color: var(--aop-teal); }

/* ── List view ──
   Toggled by adding .aoph-grid--list on the results container.
   Same card markup, rearranged into full-width rows:
   icon | name + publisher | badges (featured + scope) | sales + arrow.
   The top-row wrapper dissolves (display: contents) so icon and
   badges become row cells; order re-sequences the cells. */
.aoph-grid--list { grid-template-columns: 1fr; gap: var(--sp-12); }
.aoph-grid--list .aoph-card-link {
  display: grid;
  grid-template-columns: auto minmax(0, 1.4fr) auto auto;
  align-items: center;
  gap: var(--sp-20);
  padding: var(--sp-16) var(--sp-24);
}
.aoph-grid--list .aoph-card-top { display: contents; }
.aoph-grid--list .aoph-card-icon  { order: 1; width: 40px; height: 40px; }
.aoph-grid--list .aoph-card-icon svg { width: 20px; height: 20px; }
.aoph-grid--list .aoph-card-main  { order: 2; min-width: 0; }
.aoph-grid--list .aoph-card-badges { order: 3; flex-wrap: nowrap; }
.aoph-grid--list .aoph-card-foot  { order: 4; }
.aoph-grid--list .aoph-card-name {
  font-size: var(--text-16);
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.aoph-grid--list .aoph-card-pub {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.aoph-grid--list .aoph-card-summary { display: none; }
.aoph-grid--list .aoph-card-foot {
  margin: 0;
  padding: 0;
  border: none;
  justify-content: flex-end;
}
@media (max-width: 1023px) {
  /* Row layout gets cramped below desktop, collapse back to the
     tile shape even while list mode is active. */
  .aoph-grid--list .aoph-card-link {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding: var(--sp-24);
  }
  .aoph-grid--list .aoph-card-top { display: flex; }
  .aoph-grid--list .aoph-card-icon { width: 48px; height: 48px; }
  .aoph-grid--list .aoph-card-icon svg { width: 24px; height: 24px; }
  .aoph-grid--list .aoph-card-summary { display: block; }
  .aoph-grid--list .aoph-card-foot {
    margin-top: auto;
    padding-top: var(--sp-16);
    border-top: 1px solid var(--color-white-8);
    justify-content: space-between;
  }
}

/* ── Empty state ──
   Composes .finder-empty + .finder-empty--on-dark (components.css).
   The .finder-empty prefix on the child rules keeps them ahead of
   the primitive's generic `.finder-empty p` typography. */
.finder-empty .aoph-empty-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-h3);
  color: var(--color-white);
  margin: 0;
}
.finder-empty .aoph-empty-body {
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-body);
  color: var(--color-white-70);
  margin: 0 0 var(--sp-8) 0;
  max-width: 44ch;
}


/* ═════════════════════════════════════════════════════════════════
   7. DEV PORTAL CTA BAND (start page)
   Shell comes from the shared .cta-band primitive (components.css);
   the only page extra is a wider headline cap.
   ═════════════════════════════════════════════════════════════════ */
.aoph-cta-headline { max-width: 24ch; }


/* ═════════════════════════════════════════════════════════════════
   8. DETAIL PAGES, shared blocks
   Used by BOTH detail pages (aop-hub-extension.html and
   aop-hub-developer.html), which are built from the same anatomy:
   breadcrumb → two-column header with a fact strip → a login-gated
   area holding score, KPIs and an accordion. Content is rendered
   into the static skeletons by the page modules, using the shared
   builders in js/aop-hub-shared.js.

   Extension-only extras (media slots, joint-solution callout,
   downloads, SBOM dialog) follow in §9, developer-only extras in
   §10. Touching anything here changes both pages, that is the point.
   ═════════════════════════════════════════════════════════════════ */

/* ── 8.1 Breadcrumb ── */
.aoph-crumbs { padding-top: var(--sp-24); }
/* Back link: .arrow-link--reverse (components.css) carries type,
   the leftward slide and the focus ring; only colors live here. */
.aoph-back { color: var(--color-white-70); }
@media (hover: hover) and (pointer: fine) {
  .aoph-back:hover { color: var(--color-white); }
}

/* ── 8.2 Header: copy left, media right ── */
.aoph-head { padding: clamp(var(--sp-32), 4vw, var(--sp-56)) 0 var(--sp-section-sm); }
.aoph-head-grid {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(var(--sp-32), 5vw, var(--sp-96));
  align-items: start;
}
@media (max-width: 1023px) {
  .aoph-head-grid { grid-template-columns: 1fr; }
}

.aoph-identity {
  display: flex;
  align-items: center;
  gap: var(--sp-20);
}
.aoph-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-heading);
  font-size: var(--text-h2);
  line-height: var(--lh-tight);
  letter-spacing: -0.02em;
  color: var(--color-white);
  margin: 0;
}
.aoph-pub {
  margin: var(--sp-4) 0 0 0;
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-16);
  color: var(--color-white-70);
}
.aoph-pub a {
  color: var(--aop-teal);
  font-weight: var(--fw-medium);
  text-decoration: none;
}
@media (hover: hover) and (pointer: fine) {
  .aoph-pub a:hover { text-decoration: underline; }
}
.aoph-pub a:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.aoph-meta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-12) var(--sp-24);
  margin-top: var(--sp-24);
  padding-bottom: var(--sp-24);
  border-bottom: 1px solid var(--color-white-8);
}

.aoph-desc {
  margin: var(--sp-24) 0 0 0;
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-lead);
  line-height: 1.65; /* one-off */
  color: var(--color-white-70);
  max-width: 62ch;
}

/* ── Company avatar ──
   Initials in a teal circle, the stand-in for a company logo. Used
   at 48px in the extension page's developer teaser and at --lg in
   the developer profile header. */
.aoph-avatar {
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-circle);
  background: var(--aop-teal-soft);
  color: var(--aop-teal);
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-16);
  letter-spacing: 0.5px;
}
.aoph-avatar--lg {
  width: 76px;
  height: 76px;
  font-size: var(--text-h3);
  border: 1px solid var(--aop-teal-line);
}
/* Firmenlogo im Kreis (15.09.2026). Weisser Grund, weil Logos auf
   transparentem Hintergrund meist fuer helle Flaechen gemacht sind; auf dem
   Petrol des Initialen-Kreises waeren dunkle Marken unsichtbar. Die Luft
   zum Rand kommt ueber die Bildgroesse (72 %), NICHT ueber padding in
   Prozent: das bezieht sich auf die Breite des umgebenden Blocks. Auf dem
   Profil waren das 112 px, der Kreis wuchs auf 226 px und das Logo
   schrumpfte auf 0 x 0 (15.09.2026 im Klicktest auf Staging gesehen). */
.aoph-avatar.has-logo {
  background: #fff;
  padding: 0;
  overflow: hidden;
}
.aoph-avatar-logo {
  display: block;
  width: 72%;
  height: 72%;
  object-fit: contain;
}

/* ── Side column ──
   The header's right-hand stack: media slots on the extension page,
   logo + contact card on the developer profile. */
.aoph-side-col {
  display: flex;
  flex-direction: column;
  gap: var(--sp-16);
}

/* ── Info popover ──
   Small "?" button beside a value, with a panel that explains it
   (e.g. what the developer tiers mean). Toggled by
   HUB.initInfoPopovers (js/aop-hub-shared.js). */
.aoph-info-wrap { position: relative; display: inline-flex; }
.aoph-info {
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-circle);
  border: 1px solid var(--aop-teal-line);
  background: var(--aop-teal-faint);
  color: var(--aop-teal);
  font-family: var(--font-heading);
  font-weight: var(--fw-button);
  font-size: var(--text-12);
  line-height: 1; /* one-off */
  cursor: pointer;
  transition: background var(--duration-xs) var(--ease-smooth);
}
@media (hover: hover) and (pointer: fine) {
  .aoph-info:hover { background: var(--aop-teal-soft); }
}
.aoph-info:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 2px;
}
.aoph-info-pop {
  /* Right-aligned to the button so it always opens leftward, into
     the page, and never past the viewport edge on phones. */
  position: absolute;
  top: calc(100% + var(--sp-8));
  right: 0;
  z-index: 3;
  width: min(78vw, 320px);
  padding: var(--sp-20);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-white-15);
  background: var(--gradient-tile-dark);
  box-shadow: var(--shadow-tile-hover);
}
.aoph-info-pop[hidden] { display: none; }
.aoph-info-pop dl { margin: 0; }
.aoph-info-pop dt {
  display: flex;
  align-items: center;
  gap: var(--sp-8);
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-14);
  color: var(--color-white);
}
.aoph-info-pop dd {
  margin: 2px 0 var(--sp-12) 0;
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-14);
  line-height: 1.5; /* one-off */
  color: var(--color-white-70);
}
.aoph-info-pop dd:last-child { margin-bottom: 0; }

/* ── 8.3 Fact strip ──
   Deliberately quiet: no cards, no dividers between facts, no rule
   underneath, just a single hairline on top. It lives inside the copy
   column, so it lines up with the description and headline above it.
   The facts form a three-column grid (label over value) that collapses
   to two, then one, on narrow screens. Values are set small and light
   on purpose so the block reads as supporting metadata. */
.aoph-facts-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-20) var(--sp-32);
  margin: var(--sp-32) 0 0;
  padding: var(--sp-24) 0 0;
  border-top: 1px solid var(--color-white-8);
}
@media (max-width: 639px) {
  .aoph-facts-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.aoph-fact { min-width: 0; }
.aoph-fact dt {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-12);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--aop-teal);
  margin: 0 0 var(--sp-4) 0;
}
.aoph-fact dd {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  line-height: 1.4; /* one-off */
  color: var(--color-white-85);
  overflow-wrap: anywhere;
}
/* Product-website link: .arrow-link + external-link glyph. Keeps
   the tighter 6px gap and the 14×14 diagonal icon of this dense
   fact context; hover recolors label to teal. */
.aoph-fact dd a {
  gap: 6px;
  color: var(--color-white-85);
}
.aoph-fact dd a svg { width: 14px; height: 14px; color: var(--aop-teal); }
@media (hover: hover) and (pointer: fine) {
  .aoph-fact dd a:hover { color: var(--aop-teal); }
}

/* ── 8.4 Gated area, lock state ──
   Locked: content is blurred, clipped to a teaser height and made
   inert (JS also sets the attribute); the unlock card floats above.
   Unlocked: overlay is removed from the flow and content is normal. */
.aoph-gated {
  position: relative;
  padding: var(--sp-section-sm) 0 var(--sp-section-md);
}
.aoph-gated.is-locked {
  padding-bottom: 0;
  overflow: hidden;
}
.aoph-gated.is-locked .aoph-gated-content {
  filter: blur(9px);
  max-height: 560px;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
  /* Fade the teaser out toward the bottom edge. */
  -webkit-mask-image: linear-gradient(180deg, #000 40%, transparent 95%);
          mask-image: linear-gradient(180deg, #000 40%, transparent 95%);
}
.aoph-lock {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 2;
  align-items: center;
  justify-content: center;
  padding: var(--sp-24);
}
.aoph-gated.is-locked .aoph-lock { display: flex; }
/* Card shell comes from .aoph-modal-card (markup); the lock card
   keeps its centered stack, deeper padding and floating shadow. */
.aoph-lock-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  max-width: 520px;
  padding: clamp(var(--sp-32), 4vw, var(--sp-48));
  box-shadow: var(--shadow-tile-hover);
}
/* Lock icon: .icon-tile .icon-tile--56; kept as the hook for the
   circle shape, the stronger teal-soft wash and the gap below.
   The body + parent prefix outweighs the page-level teal-faint rule. */
body[data-page^="aop-hub"] .aoph-lock .aoph-lock-icon {
  --icon-tile-bg: var(--aop-teal-soft);
  border-radius: var(--radius-circle);
  margin-bottom: var(--sp-20);
}
.aoph-lock-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-heading);
  font-size: var(--text-h3-lg);
  letter-spacing: -0.01em;
  line-height: 1.2; /* one-off */
  color: var(--color-white);
  margin: 0 0 var(--sp-12) 0;
}
.aoph-lock-body {
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-body);
  line-height: var(--lh-body-ratio);
  color: var(--color-white-70);
  margin: 0 0 var(--sp-24) 0;
}
.aoph-lock-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-16);
}

/* ── 8.5 Gated blocks, shared rhythm ── */
.aoph-block { padding-top: var(--sp-section-sm); }
.aoph-block:first-child { padding-top: 0; }
.aoph-block-head { margin-bottom: var(--head-gap-sm); }
.aoph-block-head .aoph-eyebrow { margin-bottom: var(--sp-16); }

/* ── 8.6 KPI grid ── */
.aoph-kpi-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--sp-24);
}
/* Three numeric tiles on top (2 cols each), two list tiles below
   (3 cols each). */
.aoph-kpi        { grid-column: span 2; }
.aoph-kpi--wide  { grid-column: span 3; }
@media (max-width: 1023px) {
  .aoph-kpi, .aoph-kpi--wide { grid-column: span 3; }
}
@media (max-width: 639px) {
  .aoph-kpi, .aoph-kpi--wide { grid-column: span 6; }
}

.aoph-kpi-label {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-12);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--aop-teal);
  margin: 0 0 var(--sp-12) 0;
}
/* Oversized Poppins Light numeral, same register as the homepage
   stat numbers. */
.aoph-kpi-value {
  font-family: var(--font-heading);
  font-weight: var(--fw-light);
  font-size: var(--text-h2-lg);
  line-height: 1.05; /* one-off */
  letter-spacing: -0.02em;
  color: var(--color-white);
  margin: 0;
}
.aoph-kpi-unit {
  font-size: var(--text-16);
  font-weight: var(--fw-regular);
  color: var(--color-white-70);
  margin-left: var(--sp-8);
}
.aoph-kpi-note {
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-14);
  line-height: 1.5;
  color: var(--color-white-70);
  margin: var(--sp-12) 0 0 0;
}
/* Country / vertical KPI chips. Layout only — each <li> is a shared
   `tag tag--on-dark` (JS-generated, js/aop-hub-extension.js). */
.aoph-chips {
  list-style: none;
  margin: var(--sp-16) 0 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-8);
}

/* ── 8.7 Score: gauge + scorecard ── */
.aoph-score-grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--sp-24);
  align-items: stretch;
}
@media (max-width: 1023px) { .aoph-score-grid { grid-template-columns: 1fr; } }

.aoph-gauge-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: clamp(var(--sp-32), 3vw, var(--sp-40));
}
.aoph-gauge {
  position: relative;
  width: min(100%, 260px);
}
.aoph-gauge svg { display: block; width: 100%; height: auto; overflow: visible; }
.aoph-gauge-track,
.aoph-gauge-fill {
  fill: none;
  stroke-width: 13;
  stroke-linecap: round;
}
.aoph-gauge-track { stroke: var(--color-white-8); }
.aoph-gauge-fill {
  stroke: var(--aop-teal);
  stroke-dasharray: 100;
  /* Starts empty; JS sets the offset to (100 - score) after render,
     the transition sweeps the arc in. Paint-only, no layout. */
  stroke-dashoffset: 100;
  transition: stroke-dashoffset 900ms var(--ease-smooth);
}
@media (prefers-reduced-motion: reduce) {
  .aoph-gauge-fill { transition: none; }
}
/* Big percentage sitting inside the arc, aligned to its baseline. */
.aoph-gauge-value {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  margin: 0;
  font-family: var(--font-heading);
  font-weight: var(--fw-light);
  font-size: clamp(44px, 5vw, 60px);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--color-white);
}
.aoph-gauge-unit {
  font-size: var(--text-h3);
  font-weight: var(--fw-regular);
  color: var(--aop-teal);
  margin-left: 2px;
}
.aoph-gauge-caption {
  margin: var(--sp-20) 0 0 0;
  font-family: var(--font-heading);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white-70);
}
.aoph-gauge-caption strong {
  color: var(--color-white);
  font-weight: var(--fw-subheading);
}
.aoph-gauge-note {
  margin: var(--sp-12) 0 0 0;
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-14);
  line-height: 1.5;
  color: var(--color-white-70);
  max-width: 34ch;
}
/* Scorecard PDF button, closes the gauge card on both detail pages.
   The shared .btn carries the whole look; this only places it. The
   auto margin drops it to the bottom of the card (the card stretches
   to the taller scorecard next to it), the sibling margin below keeps
   a real gap for the case where the card is already full. */
.aoph-score-dl { margin-top: auto; }
.aoph-gauge-note,
.aophx-devscore { margin-bottom: var(--sp-24); }

.aoph-scorecard { padding: clamp(var(--sp-24), 3vw, var(--sp-32)); }
.aoph-scorecard-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-h3);
  color: var(--color-white);
  margin: 0 0 var(--sp-8) 0;
}
.aoph-scorecard-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}
.aoph-scorecard-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  grid-template-areas:
    "label count pct"
    "bar   bar   bar";
  align-items: baseline;
  column-gap: var(--sp-16);
  row-gap: var(--sp-8);
  padding: var(--sp-16) 0;
  border-top: 1px solid var(--color-white-8);
}
.aoph-scorecard-row:first-child { border-top: none; }
/* The derived total row leads the list, slightly emphasized. */
.aoph-scorecard-row--total .aoph-scorecard-label { color: var(--color-white); font-weight: var(--fw-subheading); }
.aoph-scorecard-row--total .aoph-scorecard-pct   { color: var(--aop-teal); }
.aoph-scorecard-label {
  grid-area: label;
  font-family: var(--font-heading);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white-85);
}
.aoph-scorecard-count {
  grid-area: count;
  font-family: var(--font-heading);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white-70);
  white-space: nowrap;
}
.aoph-scorecard-pct {
  grid-area: pct;
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-16);
  color: var(--color-white);
  min-width: 3.2em;
  text-align: right;
}
/* Static progress bar (no animation, width set inline by JS). */
.aoph-scorecard-bar {
  grid-area: bar;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--color-white-8);
  overflow: hidden;
}
.aoph-scorecard-bar span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--aop-teal);
}

/* Quiet note that replaces a block's content when there is nothing
   to list (e.g. a developer's first assessment has no history). */
.aoph-empty-note {
  margin: 0;
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-body);
  line-height: var(--lh-body-ratio);
  color: var(--color-white-70);
}
.aoph-empty-note[hidden] { display: none; }

/* ── 8.8 Accordion ──
   Full-width rows between hairlines, no cards. Each row is a
   <button> trigger (title + optional tag + meta + chevron) over a
   collapsible panel. Built by HUB.accordion (js/aop-hub-shared.js);
   the extension page uses it for release notes, the developer
   profile for older scorecards. Height animates via the
   grid-template-rows 0fr → 1fr trick (site accordion pattern, see
   docs/design-system.md §6), the chevron rotates via transform. */
.aoph-acc {
  list-style: none;
  margin: 0;
  padding: 0;
}
.aoph-acc-item { border-top: 1px solid var(--color-white-8); }
.aoph-acc-item:last-child { border-bottom: 1px solid var(--color-white-8); }

.aoph-acc-trigger {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-8) var(--sp-16);
  width: 100%;
  padding: var(--sp-20) 0;
  border: none;
  background: transparent;
  text-align: left;
  cursor: pointer;
}
.aoph-acc-trigger:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.aoph-acc-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-16);
  color: var(--color-white);
  transition: color var(--duration-xs) var(--ease-smooth);
}
@media (hover: hover) and (pointer: fine) {
  .aoph-acc-trigger:hover .aoph-acc-title { color: var(--aop-teal); }
  .aoph-acc-trigger:hover .aoph-acc-chevron { color: var(--color-white); }
}
/* The "Latest" marker is a shared `tag tag--accent` (JS-generated,
   js/aop-hub-extension.js). */
.aoph-acc-meta {
  margin-left: auto;
  font-family: var(--font-heading);
  font-weight: var(--fw-regular);
  font-size: var(--text-12);
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--color-white-70);
}
.aoph-acc-chevron {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--color-white-70);
  transition: transform var(--duration-base) var(--ease-smooth),
              color var(--duration-xs) var(--ease-smooth);
}
.aoph-acc-chevron svg { width: var(--icon-sm); height: var(--icon-sm); }
.aoph-acc-item.is-open .aoph-acc-chevron { transform: rotate(180deg); }

.aoph-acc-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--duration-base) var(--ease-smooth);
}
.aoph-acc-item.is-open .aoph-acc-panel { grid-template-rows: 1fr; }
.aoph-acc-panel-inner {
  overflow: hidden;
  min-height: 0;
}
.aoph-acc-body {
  color: var(--color-white-70);
  padding: 0 0 var(--sp-24) 0;
}
/* Panel ticks (release notes) follow the AOP accent. The variable has
   to sit on the list itself, .tick-list sets its own brand-blue
   default and would shadow an inherited value. */
.aoph-acc-body .tick-list { --tick-color: var(--aop-teal); }

/* Hinweiszeile ohne Haekchen (Konto noch keiner Firma zugeordnet):
   das Listen-Grid reserviert eine 16px-Icon-Spalte, in der ein Text
   ohne Icon Wort fuer Wort umbraeche. Die Zeile wird darum als
   normaler Absatz gesetzt. */
.tick-list > li.aoph-perm-note {
  display: block;
  color: var(--color-white-70);
}

/* Quiet PDF download under an older scorecard. Deliberately not a
   .btn: the history panel is a reference list, the download is a side
   action next to it. */
.aoph-scorecard-dl {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  margin-top: var(--sp-20);
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white-70);
  text-decoration: none;
  transition: color var(--duration-xs) var(--ease-smooth);
}
.aoph-scorecard-dl svg { flex-shrink: 0; }
@media (hover: hover) and (pointer: fine) {
  .aoph-scorecard-dl:hover {
    color: var(--aop-teal);
    text-decoration: underline;
    text-underline-offset: 3px;
  }
}
.aoph-scorecard-dl:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}
@media (prefers-reduced-motion: reduce) {
  .aoph-acc-panel { transition: none; }
  .aoph-acc-chevron { transition: color var(--duration-xs) var(--ease-smooth); }
}


/* ════════════════════════════════════════════════════════════════
   9. EXTENSION DETAIL PAGE ONLY (aop-hub-extension.html)
   Everything the extension page adds on top of the shared detail
   anatomy in §8: the big app icon, the joint-solution callout, the
   media column with its developer teaser, the developer-score chip
   and the download cards + SBOM dialog.
   ════════════════════════════════════════════════════════════════ */

/* ── 9.1 Hero app icon ── */
/* Large app-icon tile: .icon-tile with a one-off 76px hero size
   (teal wash via the page rule at the top). */
.aophx-app-icon {
  width: 76px;
  height: 76px;
  border-radius: var(--radius-md);
  border: 1px solid var(--aop-teal-line);
}
.aophx-app-icon svg { width: 38px; height: 38px; }

/* ── 9.2 Joint-solution callout ── */
/* Joint-solution callout, teal-washed quiet card. */
.aophx-joint {
  margin-top: var(--sp-32);
  padding: clamp(var(--sp-24), 3vw, var(--sp-32));
  border-radius: var(--radius-md);
  border: 1px solid var(--aop-teal-line);
  background: linear-gradient(120deg, var(--aop-teal-faint), transparent 60%), var(--color-white-5);
}
.aophx-joint-title {
  display: flex;
  align-items: center;
  gap: var(--sp-12);
  margin: 0 0 var(--sp-12) 0;
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-16);
  color: var(--color-white);
}
.aophx-joint-title svg { width: var(--icon-md); height: var(--icon-md); color: var(--aop-teal); flex-shrink: 0; }
.aophx-joint-body {
  margin: 0;
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-body);
  line-height: var(--lh-body-ratio);
  color: var(--color-white-70);
}

/* ── 9.3 Media galleries + developer teaser ── */
/* Media column: the Product Images gallery, the Product Videos
   gallery and then the developer teaser, stacked (the column itself
   is the shared .aoph-side-col). Each gallery is one large medium
   plus three previews; every tile opens the lightbox in §9.6. */
.aophx-media-stack {
  display: flex;
  flex-direction: column;
  gap: var(--sp-32);
}
/* Ohne Uploads (Import 08.09.) bleibt die Galerie ganz weg. */
.aophx-media-stack[hidden] { display: none; }
.aophx-media-group {
  display: flex;
  flex-direction: column;
  gap: var(--sp-12);
}
.aophx-media-label { margin: 0 0 var(--sp-4); }
.aophx-media-thumbs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-12);
}

/* Tiles compose .placeholder-slot .placeholder-slot--dark (markup);
   this resets the button chrome and adds the click affordance.
   Images keep the 16:10 of the old single slot, videos sit at 16:9 so
   the empty frame matches the clips that open in the lightbox. */
.aophx-media-tile {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  padding: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color var(--duration-xs) var(--ease-smooth),
              transform var(--duration-xs) var(--ease-smooth);
}
.aophx-media-group--video .aophx-media-tile { aspect-ratio: 16 / 9; }
/* The primitive's dashed mat is inset 16px, which crowds a preview. */
.aophx-media-thumb::before { inset: var(--sp-8); }

@media (hover: hover) and (pointer: fine) {
  .aophx-media-tile:hover {
    border-color: var(--aop-teal-line);
    transform: translateY(-2px);
  }
  .aophx-media-tile:hover .aophx-media-badge {
    background: var(--aop-teal);
    border-color: var(--aop-teal);
    color: var(--color-dark-blue);
  }
}
.aophx-media-tile:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 2px;
}

/* Echte Produktmedien (31.08.): das Bild bzw. Vorschau-Einzelbild fuellt
   die Kachel; die gestrichelte Matte des Platzhalters bleibt darunter
   verdeckt. Nur sichtbar, wenn die Firma etwas hochgeladen hat. */
.aophx-media-tile .aophx-media-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}
.aophx-lightbox-img {
  display: block;
  max-width: 100%;
  max-height: 74vh;
  margin: 0 auto;
  border-radius: var(--radius-md);
}

/* Mehr Eintraege als Kacheln (01.09.): die letzte Vorschau traegt die
   Restzahl, die Lightbox blaettert durch alle. */
.aophx-media-more {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(4, 10, 22, 0.62);
  border-radius: inherit;
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-18, 18px);
  color: var(--color-white);
  pointer-events: none;
}

/* Centered click affordance: a play triangle in the video gallery, an
   expand glyph in the image gallery. Sits above .placeholder-slot-inner
   (z-index 1), which holds the caption at the bottom of the hero. */
.aophx-media-badge {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--radius-circle);
  border: 1px solid var(--color-white-15);
  background: var(--color-white-8);
  -webkit-backdrop-filter: blur(4px);
          backdrop-filter: blur(4px);
  color: var(--color-white);
  transition: background var(--duration-xs) var(--ease-smooth),
              border-color var(--duration-xs) var(--ease-smooth),
              color var(--duration-xs) var(--ease-smooth);
}
.aophx-media-badge svg { width: var(--icon-lg); height: var(--icon-lg); }
.aophx-media-thumb .aophx-media-badge { width: 32px; height: 32px; }
.aophx-media-thumb .aophx-media-badge svg { width: var(--icon-sm); height: var(--icon-sm); }

/* ── Developer teaser ──
   The whole card is one link to the publisher's profile: avatar
   (initials) + label / name / meta, with a trailing arrow that
   slides on hover. Sits under the media slots on the right. */
/* Shell, teal hover and focus ring come from the .surface-quiet
   --faint --interactive composition (markup); this class keeps the
   row layout and its asymmetric padding. */
.aophx-dev-teaser {
  --surface-quiet-pad: var(--sp-16) var(--sp-20);
  display: flex;
  align-items: center;
  gap: var(--sp-16);
  text-decoration: none;
}
@media (hover: hover) and (pointer: fine) {
  /* Whole teaser card is the trigger, so the consumer drives the arrow-link slide. */
  .aophx-dev-teaser:hover .aophx-dev-teaser-arrow svg { transform: translateX(var(--btn-icon-shift)); }
}
.aophx-dev-teaser-main {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.aophx-dev-teaser-label {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-12);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--aop-teal);
}
.aophx-dev-teaser-name {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-16);
  line-height: var(--lh-heading);
  color: var(--color-white);
}
.aophx-dev-teaser-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px var(--sp-8);
  margin-top: 2px;
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-12);
  color: var(--color-white-70);
}
.aophx-dev-teaser-status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
/* Icon-only .arrow-link; slide driven by the card hover above. */
.aophx-dev-teaser-arrow {
  flex-shrink: 0;
  margin-left: auto;
  color: var(--aop-teal);
}

/* ── 9.4 Developer-score chip (links to the profile) ── */
/* Developer total-score chip, jumps to the company profile. */
.aophx-devscore {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-8) var(--sp-12);
  margin-top: var(--sp-24);
  padding: var(--sp-12) var(--sp-20);
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-white-15);
  background: var(--color-white-5);
  text-decoration: none;
  transition: border-color var(--duration-xs) var(--ease-smooth);
}
@media (hover: hover) and (pointer: fine) {
  .aophx-devscore:hover { border-color: var(--aop-teal-line); }
}
/* Keep the pill silhouette under the arrow-link focus ring
   (the primitive rounds the outline to --radius-sm by default). */
.aophx-devscore:focus-visible { border-radius: var(--radius-pill); }
.aophx-devscore-label {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-12);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--color-white-70);
}
.aophx-devscore-value {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-16);
  color: var(--aop-teal);
}
.aophx-devscore-name {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white);
}
.aophx-devscore svg { color: var(--aop-teal); }

/* ── 9.5 Downloads + SBOM dialog ── */
.aophx-dl-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-24);
}
@media (max-width: 1023px) { .aophx-dl-grid { grid-template-columns: 1fr; } }
.aophx-dl {
  display: flex;
  flex-direction: column;
  gap: var(--sp-20);
  padding: clamp(var(--sp-24), 3vw, var(--sp-32));
}
/* Download icon: .icon-tile .icon-tile--56 in the markup (teal wash
   via the page rule at the top). Normalized from a one-off 52px
   tile to the shared 56px register. */
.aophx-dl-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-h3);
  color: var(--color-white);
  margin: 0 0 var(--sp-8) 0;
}
.aophx-dl-body {
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-body);
  line-height: var(--lh-body-ratio);
  color: var(--color-white-70);
  margin: 0;
}
.aophx-dl-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-12);
  margin-top: auto;
}

.aophx-sbom-card .btn { align-self: flex-start; }


/* ── 9.6 Product media lightbox ── */
/* One dialog shared by both galleries in §9.3: stage on top, then a
   bar carrying prev / next, the caption and the counter. The modal
   shell mirrors the SBOM viewer above. */
.aophx-lightbox {
  width: min(94vw, 1040px);
  border: none;
  padding: 0;
  background: transparent;
  color: var(--color-white);
}
.aophx-lightbox::backdrop {
  /* Literal color: custom properties are not reliably resolved on
     ::backdrop across engines. Mirrors --color-dark-blue at ~65%.
     Keep in sync with .aoph-auth-modal::backdrop above. */
  background: rgba(10, 16, 29, 0.65);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
}
.aophx-lightbox[open] {
  animation: aoph-modal-in var(--duration-base) var(--ease-smooth);
}
@media (prefers-reduced-motion: reduce) {
  .aophx-lightbox[open] { animation: none; }
}

/* Card shell comes from .aoph-modal-card (markup); this keeps the
   column layout and tightens the frame around the medium.

   The base card pads 24-40px on every side, which is generous for a
   dialog full of text but wastes the frame here. Sides and bottom drop
   to 16px; the top keeps a 48px band so the close button has a corner
   of its own instead of sitting on the medium. Net effect is a
   tighter card AND more room for the image. */
.aophx-lightbox-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-12);
  padding: var(--sp-48) var(--sp-16) var(--sp-16);
}
/* Pulled into the card's corner, clear of the stage below: the 44px
   touch box spans 4-48px from the top, exactly where the medium
   starts. The glyph then lines up within ~2px of the medium's right
   edge. */
.aophx-lightbox .aoph-auth-close {
  top: var(--sp-4);
  right: var(--sp-4);
}
/* The three controls, close and both arrows, are bare icons: no disc,
   no ring, no fill, nothing behind them. The `border: 0` also drops
   the hairline the base .aoph-auth-close draws on hover. The 44px box
   stays as an invisible touch target; only the glyph is visible. */
.aophx-lightbox .aoph-auth-close,
.aophx-lightbox-nav {
  width: 44px;
  height: 44px;
  border: 0;
  background: none;
  color: var(--color-white);
  transition: color var(--duration-xs) var(--ease-smooth);
}
/* Hover works on the glyph itself, nothing appears around it. */
@media (hover: hover) and (pointer: fine) {
  .aophx-lightbox .aoph-auth-close:hover,
  .aophx-lightbox-nav:hover { color: var(--aop-teal); }
}
/* Kept on purpose: the focus ring only shows for keyboard users and
   is the sole indicator of where they are once the chrome is gone. */
.aophx-lightbox .aoph-auth-close:focus-visible,
.aophx-lightbox-nav:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 2px;
}

.aophx-lightbox-stage {
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Image media: the same dark placeholder as the tiles, scaled up. */
.aophx-lightbox-frame {
  width: 100%;
  aspect-ratio: 16 / 10;
  max-height: 72vh;
}
.aophx-lightbox-video {
  display: block;
  width: 100%;
  max-height: 72vh;
  border-radius: var(--radius-md);
  background: var(--color-dark-blue);
}

.aophx-lightbox-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-16);
}
.aophx-lightbox-meta {
  flex: 1;
  min-width: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: var(--sp-4) var(--sp-12);
}
.aophx-lightbox-caption {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-14);
  color: var(--color-white);
}
.aophx-lightbox-counter {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white-70);
}
/* Box, colors and hover come from the shared bare-icon rule above;
   the arrows only add their layout inside the bar. */
.aophx-lightbox-nav {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.aophx-lightbox-nav svg { width: var(--icon-md); height: var(--icon-md); }


/* ════════════════════════════════════════════════════════════════
   10. DEVELOPER PROFILE ONLY (aop-hub-developer.html)
   Everything the company profile adds on top of the shared detail
   anatomy in §8: the logo slot + contact card in the side column,
   and the public list of the developer's extensions. Score gauge,
   scorecard, KPI tiles and the older-scorecards accordion are the
   shared blocks, unchanged.
   ════════════════════════════════════════════════════════════════ */

/* ── 10.1 Side column: logo slot + contact card ── */
/* Company logo stand-in; the backend swaps it for the uploaded
   logo. Wider than tall, logos are usually horizontal. */
.aophd-logo { aspect-ratio: 16 / 7; }

/* Shell comes from .surface-quiet --faint (markup); the card keeps
   the label + link rows. */
.aophd-contact {
  --surface-quiet-pad: var(--sp-24);
  display: flex;
  flex-direction: column;
  gap: var(--sp-16);
}
.aophd-contact-label {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-12);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--aop-teal);
}
.aophd-contact-row {
  display: flex;
  align-items: center;
  gap: var(--sp-12);
}
.aophd-contact-row svg {
  width: var(--icon-sm);
  height: var(--icon-sm);
  flex-shrink: 0;
  color: var(--aop-teal);
}
.aophd-contact-row a {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white-85);
  text-decoration: none;
  overflow-wrap: anywhere;
  transition: color var(--duration-xs) var(--ease-smooth);
}
@media (hover: hover) and (pointer: fine) {
  .aophd-contact-row a:hover { color: var(--aop-teal); }
}
.aophd-contact-row a:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* ── 10.2 Extensions by this developer ──
   Public block between the header and the gated area. The cards are
   the shared .aoph-card grid from the directory (§6). */
.aophd-extensions {
  padding: var(--sp-section-sm) 0;
}


/* ════════════════════════════════════════════════════════════════
   11. DEV PORTAL DASHBOARD ONLY (aop-hub-dashboard.html)
   The signed-in user's private portal, the counterpart to the public
   company profile in §10. Card shells, tags, tick lists, avatars and
   buttons are all shared primitives; everything here is layout plus
   the four shapes this page introduces: the action list, the
   extension row, the price-free membership comparison and the
   history row.
   ════════════════════════════════════════════════════════════════ */

/* ── 11.1 Page shell ── */
/* JS swaps the two states with the hidden attribute; these beat the
   display declarations further down (same pattern as §3). */
[data-aopha-locked][hidden],
[data-aopha-portal][hidden] { display: none; }

/* Logged out: one centered card, no blurred teaser. These are the
   visitor's own account details, there is nothing to preview. */
.aopha-lock-screen { padding: var(--sp-section-md) 0; }
.aopha-lock-screen-inner {
  display: flex;
  justify-content: center;
}

.aopha-block { padding-top: var(--sp-section-sm); }
.aopha-block--last { padding-bottom: var(--sp-section-md); }

.aopha-head { padding: var(--sp-section-sm) 0 0; }
.aopha-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-heading);
  font-size: var(--text-hero);
  letter-spacing: -0.02em;
  line-height: 1.1; /* one-off */
  color: var(--color-white);
  margin: 0 0 var(--sp-20) 0;
}
.aopha-lede { max-width: 62ch; }

/* Section head: title left, primary action right. */
.aopha-section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-20);
  margin-bottom: var(--head-gap-sm);
}
.aopha-section-head .aoph-eyebrow { margin-bottom: var(--sp-16); }
.aopha-section-head .aoph-h2 { margin-bottom: 0; }

/* ── 11.2 Top row: account · company · action needed ── */
.aopha-top-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 0.9fr);
  gap: var(--sp-20);
  align-items: start;
}
@media (max-width: 1023px) {
  .aopha-top-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  /* The action card keeps full width below the two profile cards. */
  .aopha-card--action { grid-column: 1 / -1; }
}
@media (max-width: 639px) {
  .aopha-top-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Shell comes from .surface-quiet (markup); the card owns its stack. */
.aopha-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-20);
  height: 100%;
}
.aopha-card-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-h3);
  letter-spacing: -0.01em;
  color: var(--color-white);
  margin: 0;
}
.aopha-card-label {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-12);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--aop-teal);
  margin: 0;
}

.aopha-identity {
  display: flex;
  align-items: center;
  gap: var(--sp-16);
}
.aopha-identity-text { min-width: 0; }
.aopha-identity-name {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-16);
  color: var(--color-white);
  margin: 0;
  overflow-wrap: anywhere;
}
.aopha-identity-meta {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white-70);
  margin: 4px 0 0 0;
  overflow-wrap: anywhere;
}

.aopha-role-tags { margin: 0; }

/* A label with its own list, tighter than the card's own stack gap. */
.aopha-card-group {
  display: flex;
  flex-direction: column;
  gap: var(--sp-12);
}
/* Ticks follow the AOP accent. The variable has to sit on the list
   itself, .tick-list sets its own brand-blue default. */
.aopha-card-group .tick-list { --tick-color: var(--aop-teal); }

/* Push the action row to the bottom so cards of different heights
   still line their buttons up. */
.aopha-card-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-16);
  margin-top: auto;
  padding-top: var(--sp-4);
}
.aopha-card-link { font-size: var(--text-14); }

/* Facts inside the company card, label over value. */
.aopha-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-16);
  margin: 0;
}
.aopha-fact dt {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-11);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--color-white-70);
  margin-bottom: 6px;
}
.aopha-fact dd {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-14);
  color: var(--color-white);
  margin: 0;
}

/* Action-needed card: the one card on the page that carries an
   accent, because it is the only one asking for something. */
.aopha-card--action {
  --surface-quiet-bg: var(--aop-teal-faint);
  --surface-quiet-border: var(--aop-teal-line);
}
.aopha-card-title--action {
  display: flex;
  align-items: center;
  gap: var(--sp-12);
}
.aopha-alert-icon {
  display: inline-flex;
  color: var(--aop-teal);
}
.aopha-alert-icon svg { width: var(--icon-sm); height: var(--icon-sm); }

.aopha-actions {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-16);
}
.aopha-action {
  display: flex;
  gap: var(--sp-12);
  padding-top: var(--sp-16);
  border-top: 1px solid var(--color-white-8);
}
.aopha-action:first-child { padding-top: 0; border-top: 0; }
.aopha-action-icon {
  flex-shrink: 0;
  display: inline-flex;
  color: var(--aop-teal);
  margin-top: 2px;
}
.aopha-action-icon svg { width: var(--icon-sm); height: var(--icon-sm); }
.aopha-action-body { min-width: 0; }
.aopha-action-label {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-14);
  color: var(--color-white);
  margin: 0;
}
.aopha-action-detail {
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-14);
  line-height: 1.5;
  color: var(--color-white-70);
  margin: 6px 0 0 0;
}
.aopha-action-due {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-11);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--aop-teal);
  margin: var(--sp-8) 0 0 0;
}

/* ── 11.3 Resources + download row ── */
.aopha-links-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-20);
  align-items: start;
}
@media (max-width: 900px) {
  .aopha-links-grid { grid-template-columns: minmax(0, 1fr); }
}
.aopha-links-side {
  display: flex;
  flex-direction: column;
  gap: var(--sp-20);
}

.aopha-linklist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-12);
}
.aopha-linkrow {
  display: flex;
  align-items: center;
  gap: var(--sp-16);
  padding: var(--sp-12) var(--sp-16);
  border: 1px solid var(--color-white-8);
  border-radius: var(--radius-md);
  text-decoration: none;
  transition: border-color var(--duration-xs) var(--ease-smooth),
              background-color var(--duration-xs) var(--ease-smooth);
}
@media (hover: hover) and (pointer: fine) {
  .aopha-linkrow:hover {
    border-color: var(--aop-teal-line);
    background: var(--aop-teal-tint);
  }
  .aopha-linkrow:hover .aopha-linkrow-arrow { transform: translateX(var(--btn-icon-shift)); }
}
.aopha-linkrow:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 2px;
}
.aopha-linkrow-icon { flex-shrink: 0; }
.aopha-linkrow-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1;
}
.aopha-linkrow-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-14);
  color: var(--color-white);
}
.aopha-linkrow-note {
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-14);
  line-height: 1.4;
  color: var(--color-white-70);
}
.aopha-linkrow-arrow {
  flex-shrink: 0;
  color: var(--aop-teal);
  transition: transform var(--duration-xs) var(--ease-smooth);
}

/* Standalone hub link, same row anatomy without the icon tile. */
.aopha-hub-link {
  display: flex;
  align-items: center;
  gap: var(--sp-16);
  text-decoration: none;
  transition: border-color var(--duration-xs) var(--ease-smooth);
}
@media (hover: hover) and (pointer: fine) {
  .aopha-hub-link:hover { border-color: var(--aop-teal-line); }
  .aopha-hub-link:hover .aopha-linkrow-arrow { transform: translateX(var(--btn-icon-shift)); }
}
.aopha-hub-link:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 2px;
}

/* The one loud action in this row. */
.aopha-download {
  width: 100%;
  padding-top: var(--sp-20);
  padding-bottom: var(--sp-20);
}
/* Gesperrt, solange kein Installer im Speicher liegt (26.08.). */
.aopha-download:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* ── Dezente Scrollbalken (30.08.) ─────────────────────────────
   Die Standard-Scrollbalken des Systems (heller Kasten mit Pfeilen)
   stachen aus der dunklen Plattform heraus, besonders in Dialogen.
   Schmale, halbtransparente Daumen auf unsichtbarer Schiene, ueberall:
   Seite, Dialoge, Tabellen mit Querscroll, Textfelder.
   Headless-Screenshots zeichnen Scrollbalken nicht, die Pixel-Paritaet
   bleibt davon unberuehrt. */
html {
  scrollbar-width: thin;                      /* Firefox */
  scrollbar-color: var(--color-white-25, rgba(255, 255, 255, 0.25)) transparent;
}
*::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
*::-webkit-scrollbar-track {
  background: transparent;
}
*::-webkit-scrollbar-thumb {
  background-color: rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  /* Luft zwischen Daumen und Rand: der Rahmen ist transparent und wird
     vom Hintergrund abgezogen, so wirkt der Daumen schmaler. */
  border: 2px solid transparent;
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover {
  background-color: rgba(255, 255, 255, 0.32);
}
*::-webkit-scrollbar-corner {
  background: transparent;
}
*::-webkit-scrollbar-button {
  display: none;
  width: 0;
  height: 0;
}

/* Bewusst entfernte Prototyp-Elemente (27.08.): fuer Besucher unsichtbar,
   der Paritaetstest blendet sie fuer den Pixelvergleich wieder ein
   (tests/visual/prepare-page.js, DELIBERATE_REMOVALS). */
[data-aoph-removed] { display: none !important; }

/* Firmenprofil schreibgeschuetzt (Editoren/Betrachter, 27.08.):
   die Erklaerung ueber dem Formular. */
.aophc-readonly-note {
  border: 1px dashed var(--color-white-15);
  border-radius: var(--radius-md);
  padding: var(--sp-12) var(--sp-16);
  margin-bottom: var(--sp-24);
  max-width: 62ch;
}

/* ── Download-Bereich (26.08.) ──
   Die SDK-Kopfzeile traegt keinen Verweis: sie ist Ueberschrift der
   Liste darunter, nicht selbst ein Ziel. */
.aopha-linkrow--static { cursor: default; }
@media (hover: hover) and (pointer: fine) {
  .aopha-linkrow--static:hover {
    border-color: var(--color-white-8);
    background: none;
  }
}

/* Die hochgeladenen SDKs, eingerueckt unter ihrer Kopfzeile. */
.aopha-sdk-list {
  list-style: none;
  margin: var(--sp-8) 0 0 var(--sp-24);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
}
.aopha-sdk-list .aopha-linkrow {
  cursor: pointer;
  width: 100%;
  background: none;
  font: inherit;
  text-align: left;
}

/* Leere Zustaende: kein SDK, kein Installer. */
.aopha-empty-note {
  color: var(--color-white-70);
  font-size: var(--text-14);
  line-height: 1.5;
  border: 1px dashed var(--color-white-15);
  border-radius: var(--radius-md);
  padding: var(--sp-12) var(--sp-16);
  margin: var(--sp-8) 0 0 var(--sp-24);
}
.aopha-winguard-note {
  margin: var(--sp-12) 0 0;
  text-align: center;
}

/* ── 11.4 Extension rows ──
   One row per portal record: identity, status, license, actions.
   Cells carry their own label so the row still reads correctly once
   it stacks on narrow screens. */
.aopha-ext-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-12);
}
.aopha-ext-row {
  display: grid;
  grid-template-columns: minmax(0, 2.2fr) minmax(0, 1.4fr) minmax(0, 1fr) auto;
  gap: var(--sp-20);
  align-items: start;
  padding: var(--sp-24);
  border: 1px solid var(--color-white-8);
  border-radius: var(--radius-md);
  background: var(--color-white-2);
}
@media (max-width: 1279px) {
  .aopha-ext-row {
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, 1fr);
  }
  .aopha-ext-actions { grid-column: 1 / -1; }
}
@media (max-width: 639px) {
  .aopha-ext-row {
    grid-template-columns: minmax(0, 1fr);
    padding: var(--sp-20);
  }
}

.aopha-ext-main {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-8);
  min-width: 0;
}
.aopha-ext-name {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-16);
  color: var(--color-white);
  margin: 0;
}
.aopha-ext-tags { margin: 0; }
.aopha-ext-view { font-size: var(--text-14); }

.aopha-ext-cell {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.aopha-ext-cell-label {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-11);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--color-white-70);
}
.aopha-ext-status,
.aopha-ext-license {
  font-family: var(--font-heading);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white);
}
.aopha-ext-status {
  display: flex;
  align-items: center;
  gap: var(--sp-8);
}
/* Status marker. Tone is set by the record's status, never by the
   consumer, see STATUS in js/aop-hub-dashboard.js. */
.aopha-ext-dot {
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  border-radius: var(--radius-circle);
  background: var(--color-white-15);
}
.aopha-ext-dot--progress { background: var(--aop-teal); opacity: 0.55; }
.aopha-ext-dot--ok       { background: var(--aop-teal); }
.aopha-ext-dot--wait     { background: var(--color-white-70); }
.aopha-ext-dot--error    { background: var(--color-error-on-dark); }
.aopha-ext-dot--off      { background: var(--color-white-15); }

.aopha-ext-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-12);
}
.aopha-ext-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-8);
}
.aopha-ext-valid {
  display: flex;
  align-items: center;
  gap: var(--sp-8);
  font-family: var(--font-heading);
  font-weight: var(--fw-regular);
  font-size: var(--text-12);
  color: var(--color-white-70);
  margin: 0;
}
/* Assessment runs out inside twelve months. Red is informational
   here (valid / about to expire), not decoration. */
.aopha-ext-valid.is-warning { color: var(--color-error-on-dark); }
.aopha-ext-valid-icon {
  display: inline-flex;
  flex-shrink: 0;
}
.aopha-ext-valid-icon svg { width: 14px; height: 14px; }

/* ── 11.5 Membership, price-free comparison ──
   The percentages are derived from the AOP service price list; no
   amount is ever printed on this page (see the design doc,
   docs/superpowers/specs/2026-08-04-aop-hub-dashboard-design.md). */
.aopha-member {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(var(--sp-24), 3vw, var(--sp-48));
  align-items: start;
  padding: var(--card-pad-lg);
}
@media (max-width: 1023px) {
  .aopha-member { grid-template-columns: minmax(0, 1fr); }
}
.aopha-member-stat {
  font-family: var(--font-heading);
  font-weight: var(--fw-heading);
  font-size: var(--text-h2-lg);
  line-height: 1.05; /* one-off */
  letter-spacing: -0.02em;
  color: var(--aop-teal);
  margin: 0 0 var(--sp-12) 0;
}
.aopha-member-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-h3-lg);
  letter-spacing: -0.01em;
  line-height: 1.2; /* one-off */
  color: var(--color-white);
  margin: 0 0 var(--sp-16) 0;
}
.aopha-member-body {
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-body);
  line-height: var(--lh-body-ratio);
  color: var(--color-white-70);
  margin: 0 0 var(--sp-24) 0;
}
.aopha-member-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-16);
}

/* Wide table scrolls inside its own container, the page never does. */
.aopha-member-tablewrap { overflow-x: auto; }
.aopha-compare {
  width: 100%;
  min-width: 460px;
  border-collapse: collapse;
  text-align: left;
}
.aopha-compare-caption {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-12);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--aop-teal);
  text-align: left;
  padding-bottom: var(--sp-16);
}
.aopha-compare th,
.aopha-compare td {
  padding: var(--sp-12) var(--sp-16);
  border-bottom: 1px solid var(--color-white-8);
  vertical-align: middle;
}
.aopha-compare thead th {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-11);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--color-white-70);
  white-space: nowrap;
}
.aopha-compare tbody th {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white);
}
.aopha-compare td {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white-70);
}
.aopha-compare tbody tr:last-child th,
.aopha-compare tbody tr:last-child td { border-bottom: 0; }

/* The Premium column is the point of the table, tint the whole
   column instead of decorating individual cells. */
.aopha-compare-col-premium {
  background: var(--aop-teal-faint);
  color: var(--color-white);
}
.aopha-compare thead .aopha-compare-col-premium { color: var(--aop-teal); }
.aopha-compare-save {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-14);
  color: var(--aop-teal);
}
.aopha-compare-no { color: var(--color-white-15); }

.aopha-member-note {
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-14);
  color: var(--color-white-70);
  margin: var(--sp-16) 0 0 0;
}

/* ── 11.6 History rows, orders + accepted terms ── */
.aopha-history {
  list-style: none;
  margin: 0;
  padding: 0;
}
.aopha-history-row {
  display: grid;
  grid-template-columns: 140px minmax(0, 1fr) minmax(0, auto) auto;
  gap: var(--sp-20);
  align-items: center;
  padding: var(--sp-16) 0;
  border-bottom: 1px solid var(--color-white-8);
}
.aopha-history-row:first-child { border-top: 1px solid var(--color-white-8); }
@media (max-width: 767px) {
  .aopha-history-row {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--sp-8) var(--sp-16);
  }
  .aopha-history-item { grid-column: 1 / -1; order: 2; }
  .aopha-history-meta { order: 3; }
  .aopha-history-link { order: 4; justify-self: end; }
}
.aopha-history-date {
  font-family: var(--font-heading);
  font-weight: var(--fw-regular);
  font-size: var(--text-11);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-white-70);
}
.aopha-history-item {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white);
}
.aopha-history-meta {
  font-family: var(--font-heading);
  font-weight: var(--fw-regular);
  font-size: var(--text-12);
  letter-spacing: 0.5px;
  color: var(--color-white-70);
}
.aopha-history-link { font-size: var(--text-14); }


/* ════════════════════════════════════════════════════════════════
   12. COMPANY PROFILE & TEAM ONLY (aop-hub-company.html)
   The company's private administration screen: the profile form
   that feeds the public developer page, and the team tables. Cards,
   fields, tags, avatars and buttons are shared primitives; what
   lives here is layout plus the four shapes this page introduces:
   the form section, the sticky save bar, the stat card and the
   team table.
   ════════════════════════════════════════════════════════════════ */

/* ── 12.1 Page shell ── */
/* JS swaps the two states with the hidden attribute; these beat the
   display declarations further down (same pattern as §3 and §11). */
[data-aophc-locked][hidden],
[data-aophc-page][hidden] { display: none; }

/* Screen-reader-only text for this page. The project has no global
   utility for it, and one page is a poor reason to add one to the
   system, so it stays prefixed like everything else here. */
.aophc-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ── Rueckmeldungen als Toast (27.08.) ─────────────────────────
   Vorher war die Meldung eine randlose Zeile oben im Inhalt: wer nach
   einer Aktion weiter unten stand, sah sie nie, und optisch klebte sie
   am "View public profile"-Knopf. Jetzt schwebt sie fest unten in der
   Mitte — sichtbar bei jeder Scroll-Position, auf jeder Portal- und
   Verwaltungsseite, fuer jede Rolle. Vorlesbar bleibt sie wie gehabt:
   role="status" und aria-live stehen im Markup, sichtbar wird sie erst
   mit einer Meldung (Klasse is-visible, gesetzt vom announce() der
   jeweiligen Seite). */
[data-aophc-live].is-visible,
[data-aopha-live].is-visible {
  position: fixed;
  left: 50%;
  bottom: clamp(16px, 4vh, 40px);
  transform: translateX(-50%);
  z-index: 300;
  width: max-content;
  max-width: min(560px, calc(100vw - 32px));
  height: auto;
  margin: 0;
  padding: var(--sp-12) var(--sp-20);
  overflow: visible;
  clip: auto;
  white-space: normal;

  border-radius: var(--radius-md, 8px);
  border: 1px solid var(--aop-teal-line);
  background: var(--gradient-tile-dark);
  box-shadow: var(--shadow-mega);

  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  line-height: 1.5;
  color: var(--color-white);

  animation: aoph-toast-in 200ms ease-out;
}

/* Ein Fehler unterscheidet sich von einer Bestaetigung, ohne dass man
   den Satz lesen muss. */
[data-aophc-live].is-visible.is-error,
[data-aopha-live].is-visible.is-error {
  border-color: var(--color-error-on-dark);
  color: var(--color-error-on-dark);
}

@keyframes aoph-toast-in {
  from { opacity: 0; transform: translate(-50%, 8px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

@media (prefers-reduced-motion: reduce) {
  [data-aophc-live].is-visible,
  [data-aopha-live].is-visible { animation: none; }
}

.aophc-lock-screen { padding: var(--sp-section-md) 0; }
.aophc-lock-screen-inner {
  display: flex;
  justify-content: center;
}

.aophc-head { padding: var(--sp-section-sm) 0 0; }
.aophc-back {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  font-family: var(--font-heading);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white-70);
  text-decoration: none;
  margin-bottom: var(--sp-24);
  transition: color var(--duration-xs) var(--ease-smooth);
}
@media (hover: hover) and (pointer: fine) {
  .aophc-back:hover { color: var(--color-white); }
}
.aophc-back:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 3px;
}

.aophc-head-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-24);
}
.aophc-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-heading);
  font-size: var(--text-hero);
  letter-spacing: -0.02em;
  line-height: 1.1; /* one-off */
  color: var(--color-white);
  margin: 0 0 var(--sp-20) 0;
}
.aophc-lede { max-width: 62ch; }

.aophc-block { padding-top: var(--sp-section-sm); }
.aophc-block--last { padding-bottom: var(--sp-section-md); }

/* ── 12.2 Company form ──
   Section = a quiet card; fields come from the shared .aoph-field /
   .input--dark pair the auth dialog already uses. */
.aophc-h2 { margin-bottom: var(--head-gap-sm); }

.aophc-form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-24);
}
.aophc-formsection { padding: var(--sp-32); }
.aophc-formsection-title {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-h3);
  color: var(--color-white);
  margin: 0 0 var(--sp-8) 0;
}
.aophc-formsection-note {
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-14);
  line-height: 1.55;
  color: var(--color-white-70);
  max-width: 60ch;
  margin: 0 0 var(--sp-24) 0;
}
.aophc-formsection-title + .aophc-field-grid,
.aophc-formsection-title + .aoph-field,
.aophc-formsection-title + .aophc-logo-row { margin-top: var(--sp-24); }

.aophc-field-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-16);
}
.aophc-field--wide { grid-column: 1 / -1; }
.aophc-textarea {
  resize: vertical;
  min-height: 160px;
  line-height: 1.55;
}

.aophc-field-hint,
.aophc-count {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-12);
  color: var(--color-white-70);
  margin: 0;
}
.aophc-count.is-over { color: var(--color-error-on-dark); }

.aophc-field-error {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-12);
  color: var(--color-error-on-dark);
}
.aophc-field-error[hidden] { display: none; }
/* The invalid state rides on aria-invalid, so the styling can never
   disagree with what a screen reader is told. */
.input--dark[aria-invalid="true"] { border-color: var(--color-error-on-dark); }

.aophc-logo-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-24);
}
.aophc-logo-slot {
  width: 200px;
  height: 96px;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
/* .btn setzt display: inline-flex und schlaegt damit das hidden-Attribut;
   ohne diese Regel stand "Remove logo" auch ohne Logo da (15.09.2026). */
[data-aophc-logo-remove][hidden] { display: none; }

.aophc-logo-slot img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.aophc-logo-name {
  font-family: var(--font-body);
  font-size: var(--text-12);
  color: var(--color-white-70);
}
.aophc-logo-actions {
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
  align-items: flex-start;
}
/* The file input sits inside the label, so the label IS the button. */
.aophc-logo-btn { cursor: pointer; }

.aophc-formsection--managed { border-style: dashed; }
.aophc-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--sp-20);
  margin: 0;
}
.aophc-fact dt {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-11);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-white-70);
  margin-bottom: var(--sp-4);
}
.aophc-fact dd {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white);
  margin: 0;
}

/* ── Sticky save bar ──
   Pinned to the bottom of the viewport while the form is dirty. */
.aophc-savebar {
  position: sticky;
  bottom: var(--sp-16);
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-16);
  padding: var(--sp-16) var(--sp-24);
  border: 1px solid var(--aop-teal-line);
  border-radius: var(--radius-md);
  background: var(--color-dark-blue);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.aophc-savebar[hidden] { display: none; }
.aophc-savebar-text {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  color: var(--color-white);
  margin: 0;
}
.aophc-savebar-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-12);
}

@media (max-width: 700px) {
  .aophc-formsection { padding: var(--sp-24); }
  .aophc-field-grid { grid-template-columns: 1fr; }
}

/* ── 12.3 Team: stats, tabs, tables ── */
.aophc-section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-20);
  margin-bottom: var(--head-gap-sm);
}

.aophc-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sp-16);
  list-style: none;
  margin: 0 0 var(--sp-24) 0;
  padding: 0;
}
.aophc-stat { padding: var(--sp-20) var(--sp-24); }
.aophc-stat-label {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-11);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-white-70);
  margin: 0;
}
.aophc-stat-value {
  font-family: var(--font-heading);
  font-weight: var(--fw-heading);
  font-size: var(--text-h2);
  line-height: 1.1; /* one-off */
  color: var(--color-white);
  margin: var(--sp-8) 0 var(--sp-4) 0;
}
.aophc-stat-note {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-12);
  color: var(--color-white-70);
  margin: 0;
}

.aophc-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-8);
  margin-bottom: var(--sp-16);
}

.aophc-tabpanel { padding: var(--sp-8) var(--sp-8) var(--sp-16); }
.aophc-tabpanel[hidden] { display: none; }

/* The table scrolls inside its own box, the page never does. */
.aophc-tablewrap { overflow-x: auto; }

.aophc-table {
  width: 100%;
  min-width: 720px;
  border-collapse: collapse;
  font-family: var(--font-body);
  font-size: var(--text-14);
  color: var(--color-white);
}
.aophc-table th,
.aophc-table td {
  text-align: left;
  padding: var(--sp-16);
  border-bottom: 1px solid var(--color-white-8);
  vertical-align: middle;
}
.aophc-table thead th {
  font-family: var(--font-heading);
  font-weight: var(--fw-label);
  font-size: var(--text-11);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-white-70);
  white-space: nowrap;
}
.aophc-table tbody tr:last-child td { border-bottom: 0; }

.aophc-person {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-12);
}
.aophc-avatar-sm {
  width: 32px;
  height: 32px;
  font-size: var(--text-11);
  flex: 0 0 auto;
}
.aophc-person-name {
  font-weight: var(--fw-regular);
  color: var(--color-white);
  white-space: nowrap;
}
.aophc-you-tag { margin-left: var(--sp-4); }
.aophc-cell-mail { color: var(--color-white-70); }
.aophc-cell-actions { width: 56px; text-align: right; }

.aophc-status {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  white-space: nowrap;
}
.aophc-status-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--radius-circle);
  flex: 0 0 auto;
  background: var(--color-white-15);
}
.aophc-status--ok   .aophc-status-dot { background: var(--aop-teal); }
.aophc-status--wait .aophc-status-dot { background: var(--color-white-70); }
.aophc-status--off  .aophc-status-dot { background: var(--color-white-15); }
.aophc-status--off { color: var(--color-white-70); }

.aophc-empty-note {
  font-family: var(--font-body);
  font-weight: var(--fw-body);
  font-size: var(--text-14);
  color: var(--color-white-70);
  padding: var(--sp-16);
  margin: 0;
}

@media (max-width: 900px) {
  .aophc-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── 12.4 Row menus and dialogs ── */
.aophc-rowmenu { position: relative; }
.aophc-rowmenu-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--color-white-70);
  cursor: pointer;
  transition:
    color var(--duration-xs) var(--ease-smooth),
    border-color var(--duration-xs) var(--ease-smooth);
}
.aophc-rowmenu-btn svg { width: 18px; height: 18px; }
@media (hover: hover) and (pointer: fine) {
  .aophc-rowmenu-btn:hover {
    color: var(--color-white);
    border-color: var(--color-white-15);
  }
}
.aophc-rowmenu-btn:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 2px;
}

.aophc-menu {
  position: absolute;
  right: 0;
  top: calc(100% + var(--sp-4));
  z-index: 10;
  min-width: 210px;
  list-style: none;
  margin: 0;
  padding: var(--sp-8);
  border: 1px solid var(--color-white-15);
  border-radius: var(--radius-md);
  background: var(--color-dark-blue);
  box-shadow: var(--shadow-tile-hover);
  text-align: left;
}
.aophc-menu-item {
  display: block;
  width: 100%;
  padding: var(--sp-8) var(--sp-12);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--text-14);
  color: var(--color-white);
  text-align: left;
  cursor: pointer;
  transition: background var(--duration-xs) var(--ease-smooth);
}
@media (hover: hover) and (pointer: fine) {
  .aophc-menu-item:hover { background: var(--color-white-8); }
}
.aophc-menu-item:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: -2px;
}
.aophc-menu-item--danger { color: var(--color-error-on-dark); }

.aophc-dialog-fields {
  display: flex;
  flex-direction: column;
  gap: var(--sp-16);
}
.aophc-dialog-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--sp-12);
  margin-top: var(--sp-24);
}
.aophc-dialog .input--dark:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
/* The one destructive button on the page. Overrides the fill of
   .btn--filled .btn--blue without leaving the button system. */
.aophc-btn-danger {
  background: var(--color-error-on-dark);
  border-color: var(--color-error-on-dark);
  color: var(--color-dark-blue);
}

/* ── 12.5 Small screens ──
   Below 700px both tables stop being tables: every row becomes a
   card and each cell carries its column name from the data-label
   the renderers emit. Vertical scrolling beats sideways scrolling
   on a phone. The thead block repeats what .aophc-sr does on
   purpose, the class cannot be used here because the header row
   must be hidden only inside this media query. */
@media (max-width: 700px) {
  .aophc-tablewrap { overflow-x: visible; }
  .aophc-table { min-width: 0; }
  .aophc-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .aophc-table tr {
    display: block;
    padding: var(--sp-16) 0;
    border-bottom: 1px solid var(--color-white-8);
  }
  .aophc-table tbody tr:last-child { border-bottom: 0; }
  .aophc-table td {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-16);
    padding: var(--sp-8) var(--sp-16);
    border-bottom: 0;
  }
  .aophc-table td::before {
    content: attr(data-label);
    font-family: var(--font-heading);
    font-weight: var(--fw-label);
    font-size: var(--text-11);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-white-70);
    flex: 0 0 auto;
  }
  /* The actions cell has no label and stays right-aligned. */
  .aophc-cell-actions {
    width: auto;
    justify-content: flex-end;
  }
  .aophc-cell-actions::before { content: none; }
  .aophc-person-name { white-space: normal; }
  .aophc-stats { grid-template-columns: 1fr; }
  .aophc-savebar {
    flex-direction: column;
    align-items: stretch;
  }
  .aophc-savebar-actions { justify-content: flex-end; }
}

/* Stand der manuellen KPI-Pflege (01.09.), rechtsbuendig unter dem
   Raster — Uebergangsloesung bis zur AdVision-API. */
.aoph-kpi-updated {
  margin-top: var(--sp-12);
  text-align: right;
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-12);
  color: var(--color-white-70);
}

/* Aufklappbare Scorecard-Zeile: der Wortlaut der SRFI-Antwort
   (Vorgabe David 01.09.). Nur Zeilen mit Text sind bedienbar. */
.aoph-scorecard-row--toggle { cursor: pointer; }
.aoph-scorecard-row--toggle:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 2px;
  border-radius: 4px;
}
.aoph-scorecard-chev {
  width: 14px;
  height: 14px;
  margin-left: var(--sp-8);
  vertical-align: -2px;
  opacity: 0.6;
  transition: transform 0.2s ease;
}
.aoph-scorecard-row--toggle.is-open .aoph-scorecard-chev { transform: rotate(180deg); }
.aoph-scorecard-answer {
  grid-column: 1 / -1;
  display: none;
  font-family: var(--font-body);
  font-size: var(--text-14);
  line-height: 1.6;
  color: var(--color-white-70);
}
.aoph-scorecard-row--toggle.is-open .aoph-scorecard-answer { display: block; }

/* ─────────────────────────────────────────────
   Hinweis zu Cookies und lokaler Speicherung im Footer (REQ-065, 07.09.)
   ───────────────────────────────────────────── */
.aoph-footer-notice {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-12) var(--sp-24);
  padding-top: var(--sp-16);
  padding-bottom: var(--sp-16);
  border-top: 1px solid var(--color-white-8);
}
.aoph-footer-notice-text {
  margin: 0;
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-14);
  line-height: 1.5;
  color: var(--color-white-70);
  max-width: 64ch;
}
.aoph-footer-notice-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-20);
  flex-wrap: wrap;
}

/* ─────────────────────────────────────────────
   Rechtsseiten (aop-hub-legal.html)
   ───────────────────────────────────────────── */
.aoph-legal {
  background: var(--color-dark-blue);
  color: var(--color-white);
}
.aoph-legal-inner {
  padding-top: clamp(var(--sp-40), 6vw, var(--sp-64));
  padding-bottom: clamp(var(--sp-48), 8vw, var(--sp-96));
  max-width: 72ch;
}
.aoph-legal-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-8);
  margin: var(--sp-24) 0 var(--sp-32) 0;
}
.aoph-legal-body p,
.aoph-legal-body li {
  font-family: var(--font-body);
  font-weight: var(--fw-regular);
  font-size: var(--text-body);
  line-height: var(--lh-body-ratio);
  color: var(--color-white-70);
}
.aoph-legal-body p { margin: 0 0 var(--sp-16) 0; }
.aoph-legal-body a { color: var(--aop-teal); text-decoration: underline; }
.aoph-legal-h2 {
  font-family: var(--font-heading);
  font-weight: var(--fw-subheading);
  font-size: var(--text-h3);
  color: var(--color-white);
  margin: var(--sp-32) 0 var(--sp-12) 0;
}
.aoph-legal-list {
  margin: 0 0 var(--sp-16) 0;
  padding-left: 1.2em;
}
.aoph-legal-list li { margin-bottom: var(--sp-8); }
.aoph-legal-source {
  margin-top: var(--sp-40);
  font-family: var(--font-body);
  font-size: var(--text-12);
  color: var(--color-white-70);
}
.aoph-legal-source a { color: var(--aop-teal); text-decoration: underline; margin-left: var(--sp-8); }
/* display:flex wuerde das hidden-Attribut ueberstimmen. */
.aoph-footer-notice[hidden] { display: none; }

/* "Coming soon" (Anthony 07.09.): sichtbar, aber nicht bedienbar. Gilt
   fuer den Smart-RFI-Reiter in der Verwaltung und den Knopf im Dev Portal. */
.aoph-chip--soon,
.aopha-new-ext[aria-disabled="true"] {
  pointer-events: none;
  opacity: 0.55;
  cursor: default;
}
.aoph-soon {
  display: inline-block;
  margin-left: var(--sp-8);
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid currentColor;
  font-family: var(--font-heading);
  font-size: var(--text-11);
  font-weight: var(--fw-label);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  vertical-align: middle;
}

/* SBOM-Auskunft auf der Extension-Seite (07.09.): zwei Fakten statt Knoepfe. */
.aophx-dl-facts {
  margin: var(--sp-16) 0 0 0;
  display: grid;
  gap: var(--sp-8);
}
.aophx-dl-fact {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--sp-8) var(--sp-16);
  font-family: var(--font-body);
  font-size: var(--text-14);
}
.aophx-dl-fact dt { color: var(--color-white-70); margin: 0; }
.aophx-dl-fact dd { color: var(--color-white); font-weight: var(--fw-subheading); margin: 0; }

/* Verkaufszahlen ausgeblendet (David 16.09.2026). Die Kennzahl im
   Entwicklerprofil verschwindet ganz; Karten und Trendliste behalten ihren
   Platz, damit Pfeil und Zeilenhoehe nicht springen. */
html[data-aoph-hide-sales] .aoph-fact[data-aoph-sales] { display: none; }
html[data-aoph-hide-sales] [data-aoph-sales]:not(.aoph-fact) { visibility: hidden; }

/* Stufen-Erklaerung am Tag selbst (David 16.09.2026). Ohne sichtbares "?"
   richtet sich die Erklaerung links an der Tag-Zeile aus. */
.aoph-tag--info { cursor: help; }
.aoph-tag--info:focus-visible {
  outline: 2px solid var(--aop-teal);
  outline-offset: 2px;
}
.aoph-meta-row:has(.aoph-info[data-aoph-removed]) { position: relative; }
.aoph-info-wrap:has(> .aoph-info[data-aoph-removed]) { position: static; }
.aoph-info-wrap:has(> .aoph-info[data-aoph-removed]) .aoph-info-pop {
  left: 0;
  right: auto;
}
