/* =============================================================================
 * Reseller Portal — curated accent rules (Iris spec §3.2).
 *
 * STATIC sheet, NO reseller input. Scoped under .np-reseller so it never leaks
 * into the rest of the product.
 *
 * FALLBACKS: NEUTRAL, NEVER THE PLATFORM (GL-003 §7.3).
 * The previous rule of this sheet was "every token falls back to the PLATFORM
 * DEFAULT, so the rule still renders with the native SocialGrow look". That was
 * the defect, written down as the intent: these are CLIENT-FACING surfaces, and
 * §7.0 degrades toward the NEUTRAL, never toward us. A reseller whose brand
 * colour is missing must not be dressed in ours.
 *
 * The no-:root branch does not leave ONE token undefined — it leaves them ALL
 * undefined at once, while this sheet keeps loading. So the fallbacks are not N
 * independent choices: they are a single neutral look that has to hold together.
 * They are therefore chosen BY ROLE, not per token and not per file:
 *
 *   role                                   light              dark
 *   fill carrying a foreground             #212121 + #fafafa  #fafafa + #212121
 *   foreground on a page surface           #212121            #fafafa
 *   line (border, focus ring)              #212121            #fafafa
 *   subtle surface                         #f5f5f5            #1b1b1f
 *
 * All values come from §7.2; no new hex. LITERALS, never var(): these serve the
 * branch where the custom properties do not exist, so a var() fallback would
 * depend on the very mechanism it is compensating for.
 *
 * Before writing var(--brand-*, X): ask what ROLE the token occupies HERE. If it
 * is none of the four, do not invent one — that is a design-system entry. Iris.
 *
 * core.css is NOT touched — this is an additive layer.
 * ========================================================================== */

/* Primary button — bg / hover / active / label */
.np-reseller .button,
.np-reseller .btn-primary {
  background-color: var(--brand-primary, #212121);
  color:            var(--brand-on-primary, #fafafa);
  border-color:     var(--brand-primary-border, #212121);
}
.np-reseller .button:hover,
.np-reseller .btn-primary:hover  { background-color: var(--brand-primary-hover,  #212121); }
.np-reseller .button:active,
.np-reseller .btn-primary:active { background-color: var(--brand-primary-active, #212121); }

/* Dark half of the same roles. The rules above carry no theme qualifier, so the
   base rule is the LIGHT set and these are the dark delta — mirroring how the
   tokens themselves are emitted (:root = light, body.darkside = dark). Measured:
   the tenant dashboard renders body.darkside, so this is the reachable half. */
body.darkside.np-reseller .button,
body.darkside.np-reseller .btn-primary {
  background-color: var(--brand-primary, #fafafa);
  color:            var(--brand-on-primary, #212121);
  border-color:     var(--brand-primary-border, #fafafa);
}
body.darkside.np-reseller .button:hover,
body.darkside.np-reseller .btn-primary:hover  { background-color: var(--brand-primary-hover,  #fafafa); }
body.darkside.np-reseller .button:active,
body.darkside.np-reseller .btn-primary:active { background-color: var(--brand-primary-active, #fafafa); }

/* Link / accent text — PERIMETER of --brand-primary-text: CONTENT links and
   explicit opt-ins, never components (Iris audit 2026-08-13, P1-2; GL-003
   §7.0.2 entry pending).

   The previous blanket (`.np-reseller a`) painted EVERY anchor of the tenant,
   including CTAs whose fill is already brand-primary — measured damage: three
   defensive !important patches in subscribe alone, incl. the "brand text on
   brand fill" CTA bug. Same defect class this sheet's own containment notes
   censure in core.css: an element-wide rule painting inside someone else's
   component.

   Scope now: `a:not([class])` = prose/content links. An anchor WITH a class is
   a component and answers for its own colour. Safe failure mode: a classed
   anchor not yet styled degrades onto core.css `.darkside a` -> white =
   neutral, never platform (§7.3).

   The dark branch keeps beating the core.css `.darkside a` bleed (0,1,1) — the
   `[class]` inside :not() counts, so specificity is 0,3,2 (was 0,2,2). Do NOT
   rewrite with :where() (loses to the bleed) or @layer (non-layered core sheets
   would still win).

   Opt-in: a.ofm-button — D4 (below) measured its brand accent arrives from the
   generic rule (6.17:1 on #1e1e1e); dropping the blanket without this opt-in
   would be a regression. New opt-ins are a design-system entry: Iris. */
.np-reseller a:not([class]),
.np-reseller .link,
.np-reseller a.ofm-button { color: var(--brand-primary-text, #212121); }
body.darkside.np-reseller a:not([class]),
body.darkside.np-reseller .link { color: var(--brand-primary-text, #fafafa); }
/* Dark opt-in REST-ONLY (:not(:hover)): core's tokenized hover pair
   (core.css:614-618, on-primary over primary fill) must own the hover pixel —
   an unqualified opt-in would repaint brand-text ON brand-fill, the exact D4
   defect core.css:593-598 documents as dissolved. Vera gate 2026-08-13;
   perimeter entry pending: Iris GL-003. */
body.darkside.np-reseller a.ofm-button:not(:hover) { color: var(--brand-primary-text, #fafafa); }


/* Focus ring — accessibility: never remove the outline */
/* Role = line. The focus ring is a SAFETY affordance, so in degradation it goes
   toward the MORE visible, never the more discreet: the neutral extreme of the
   ramp on each theme is the highest-contrast choice without a brand colour. */
.np-reseller :focus-visible {
  outline: 2px solid var(--brand-focus-ring, #212121);
  outline-offset: 2px;
}
body.darkside.np-reseller :focus-visible {
  outline: 2px solid var(--brand-focus-ring, #fafafa);
}
/* On the LIGHT tenant topbar the bar IS the brand fill (rule below), so the brand
   ring on it measured 1:1 (avatar, icons). There the ring takes the colour that is
   paired with that fill: --brand-on-primary (contrast guaranteed by derivation;
   without a brand the bar is #111114 and the fallback is white). Dark is unaffected:
   the dark bar is #111114, painted elsewhere. 2026-09-24, Felix. */
body.np-reseller:not(.darkside) #topbar :focus-visible {
  outline-color: var(--brand-on-primary, #ffffff);
}
/* The topbar action link ("Add new") on the LIGHT tenant topbar, which is the brand
   fill: it took the core link colour, #3b7cff on the fill = 1.23:1 with a sample
   brand. It takes the colour paired with the fill, like the ring above. 2026-09-24. */
body.np-reseller:not(.darkside) #topbar .topbar-special-link,
body.np-reseller:not(.darkside) #topbar .topbar-special-link .icon {
  color: var(--brand-on-primary, #ffffff);
}
/* The REST of the light tenant topbar, same pairing (B17, 2026-09-24, Felix).
   Measured on #3b7cff (derived on-primary #000000): greeting "Ciao, ..." and the
   mobile menu icon were #212121 = 4.23:1 (the platform's light [A] rule in
   topbar.fragment.php), the account caret and the avatar ring #ffffff = 3.81:1;
   on a light brand (#ffcc00) caret and ring fell to 1.51:1. Everything the fill
   carries now takes the colour paired with the fill. .topbar-actions covers what
   inherits from it (search icon, action links). The avatar disc keeps its own
   #212121/#fff pair; the ring is its edge on the bar. Dark is unaffected. */
body.np-reseller:not(.darkside) #topbar .topbar-mobile-menu-icon,
body.np-reseller:not(.darkside) #topbar .topbar-actions,
body.np-reseller:not(.darkside) #topbar .topbar-actions .link:hover,
body.np-reseller:not(.darkside) #topbar .topbar-profile .greeting,
body.np-reseller:not(.darkside) #topbar .topbar-profile .arrow {
  color: var(--brand-on-primary, #ffffff);
}
body.np-reseller:not(.darkside) #topbar .topbar-profile .circle {
  border-color: var(--brand-on-primary, #ffffff);
}
/* "Renew" (a.renewtop.button, package_id = 0 only): a brand-filled button on the
   brand-filled bar, so its edge was the only thing separating it and it measured
   1.00-2.79:1 (border = --brand-primary-border). The EDGE takes the on-primary
   colour; the fill stays the brand (owner decision on .button). B17 note, Felix. */
body.np-reseller:not(.darkside) #topbar a.renewtop {
  border-color: var(--brand-on-primary, #ffffff);
}

/* Aside navigation (settings): the active and the hovered item. core.css paints
   them with the PLATFORM text accent (B17); a tenant's pages take the tenant's
   derived text colour. 0,3,2 beats core's 0,2,2 in light; the dark pair is
   0,4,3 so it beats `.darkside .asidenav ...` (0,3,2) whatever the load order. */
/* Inactive items: the prose-link rule above (`.np-reseller a:not([class])`,
   0,2,1 / dark 0,3,2) painted them brand too, so the active item was told apart
   by weight alone. They go back to the aside's neutral text (core: #212121 light,
   #fff dark) - 0,2,2 / 0,3,3 - and brand text marks only active and hover. */
.np-reseller .asidenav li a { color: inherit; }
body.darkside.np-reseller .asidenav li a { color: inherit; }
.np-reseller .asidenav li.active a,
.np-reseller .asidenav li a:hover {
  color: var(--brand-primary-text, #212121);
}
body.darkside.np-reseller .asidenav li.active a,
body.darkside.np-reseller .asidenav li a:hover {
  color: var(--brand-primary-text, #fafafa);
}

/* Header / topbar */
.np-reseller .app-topbar,
.np-reseller #topbar > div {
  /* TOPBAR - LASCIATA COM'ERA, DELIBERATAMENTE. Misurato: il  di questa
     regola vince, il  NO - resta #111114, imposto da un TERZO
     POSTO che non e' ne' questo foglio ne' i token. Applicare qui la coppia del
     ruolo spezza la coppia: il primo piano si muove, il riempimento no, e nel
     ramo senza :root si ottiene #212121 su #111114 = 1,16:1.
     Un ruolo riempimento + primo piano e' indivisibile: se il riempimento non
     e' nostro, il primo piano non lo tocchiamo. Il fallback vero di questa
     superficie vive altrove -> fronte nuovo, decide il committente. */
  background-color: var(--brand-primary, #111114);
  color:            var(--brand-on-primary, #ffffff);
}

/* Logo slot - light/dark swap via the existing .darkside class.
   NO var() FALLBACK, deliberately. These tokens are ASSETS, not colours, and
   they have no role in the §7.3 table. What to show when the tenant has no logo
   is governed IN FULL by the §7.4.b ladder (logo -> wordmark -> monogram), which
   lives in the resolver. A fallback here would be a SECOND place deciding the
   same thing, and it would silently outrank the ladder. The CSS does not decide;
   it receives. When the token is absent the declaration is invalid-at-computed-
   value-time and the property is simply not applied - which is what lets the
   ladder do its job. And never a platform asset, at any step. */
.np-reseller .brand-logo { background-image: var(--brand-logo-light); }
body.darkside.np-reseller .brand-logo { background-image: var(--brand-logo-dark); }

/* Subtle backgrounds (badge / row-hover) */
/* Subtle surface. `transparent` was neutral but not the pinned role value; it
   also meant "no tint at all", i.e. the badge silently stopped being a badge. */
.np-reseller .badge-brand,
.np-reseller .row-hover:hover { background-color: var(--brand-primary-subtle, #f5f5f5); }
body.darkside.np-reseller .badge-brand,
body.darkside.np-reseller .row-hover:hover { background-color: var(--brand-primary-subtle, #1b1b1f); }

/* =============================================================================
 * H1 FIX (QA Fase 1.4c) — brand the PRIMARY auth-page CTA.
 *
 * The auth pages (login/signup) style their submit CTA with `.auth-btn`, which is
 * neither `.button` nor `.btn-primary`, so the rules above never reach it — it
 * stays platform-grey. We add the `auth-btn-primary` MODIFIER to the two real
 * CTAs only (login submit + #signuped); the social button (#fb-login-btn) keeps
 * `.auth-btn` alone and stays neutral.
 *
 * Declarations are exactly Iris/Vera's H1 spec. The SELECTOR, however, is raised
 * from `.np-reseller` to `body.auth-page.np-reseller`: auth.css scopes its !important
 * rules as `body.auth-page .auth-btn[:hover/:active/ .mdi]` (specificity 0,2,1 / 0,3,1),
 * which OUTRANKS a two-class `.np-reseller .auth-btn-primary` (0,2,0) even with
 * !important — the brand colour would not render. Prefixing `body.auth-page`
 * (mirroring auth.css's own idiom) lifts each rule to 0,3,1 / 0,4,1 so it reliably
 * wins. It only matches on auth pages, so it is inert on dashboard surfaces.
 *
 * Auth pages carry the LIGHT token set (no body.darkside), so the button paints
 * --brand-primary (#1e6feb sample) with --brand-on-primary (#ffffff) = 4.64:1 AA —
 * self-contained, independent of the dark auth surface. Links/text stay auth.css
 * (H2): we brand the button ONLY, never the light text token on the dark surface.
 * ========================================================================== */
/* The auth page now DECLARES the theme it paints (darkside, see login.php), so
   this block is no longer an exception needing its own axis: it is simply a dark
   block, and the §7.3 table answers it without ambiguity. */
body.auth-page.darkside.np-reseller .auth-btn-primary {
  background:   var(--brand-primary, #fafafa) !important;
  color:        var(--brand-on-primary, #212121) !important;
  border-color: var(--brand-primary-border, #fafafa) !important;
}
body.auth-page.darkside.np-reseller .auth-btn-primary:hover  { background: var(--brand-primary-hover,  #fafafa) !important; }
body.auth-page.darkside.np-reseller .auth-btn-primary:active { background: var(--brand-primary-active, #fafafa) !important; }
body.auth-page.darkside.np-reseller .auth-btn-primary .mdi,
body.auth-page.darkside.np-reseller .auth-btn-primary svg    { color: var(--brand-on-primary, #212121) !important; }

/* =============================================================================
 * D4 - PROVISIONAL FALLBACK on a.ofm-button: DISSOLVED 2026-07-31, not deleted
 * early. The guard read:
 *     body.darkside.np-reseller a.ofm-button { color: #fafafa; }
 * and it carried its own dissolution condition: "re-measure first and delete
 * only once the brand colour passes without it".
 *
 * RE-MEASURED BEFORE DELETING, on painted pixels (/post @1280, tenant 900001,
 * transitions disabled, double rAF):
 *   - the recalibrated derivation is LIVE on this box: body.darkside now emits
 *     --brand-primary-text: #ae8af7 (was #9567f5).
 *   - with the guard reproduced-away, a.ofm-button "Select files" paints
 *     #ae8af7 on #1e1e1e = 6.17:1. Threshold 4.5:1. It holds on its own.
 *   - positive control in the same run: exactly ONE rule was removed (not
 *     zero), the glyph changed colour #fafafa -> #ae8af7 over the same 43
 *     glyph pixels, and an unrelated .np-reseller link already painted
 *     rgb(174,138,247) in BOTH states - so the generic link rule was already
 *     working and takes over cleanly.
 * The accent was restored by the derivation, which is what the note asked for.
 * NOT measured: the "Load more" instance named in the old note does not render
 * in this fixture (no media). Same selector, same #1e1e1e surface, same token
 * - so the arithmetic is identical, but that is INFERENCE, not a measurement.
 * ========================================================================== */
