@charset "UTF-8";
/* ==========================================================================
   Persona Studio v2 — site-chrome.css
   The seam between the SHARED site chrome (includes/nav_functions.php,
   includes/footer_functions.php, /css/nav-shared.css) and this app.

   WHY THIS FILE EXISTS, MEASURED
   partials/head.php dropped Bootstrap and Font Awesome, and v1's
   persona-studio/styles.css is no longer loaded. Between them those files were
   defining every UNPREFIXED custom property the shared chrome consumes. With
   them gone I measured, on the real page:

     .nav-container   background-color rgba(0,0,0,0)   color rgb(0,0,0)
     .banner-container background-color rgba(0,0,0,0)  font-family Times
     footer.footer-v2 background-color rgba(0,0,0,0)
     --bg-primary --surface-glass --surface-glass-hover --border-glass
     --text-primary --text-secondary --dropdown-bg --transition-speed
     --glass-background --glass-background-hover --primary-color
     --primary-color-dark --text-color                 ALL EMPTY

   i.e. the nav rendered as unstyled black-on-transparent Times, and the auth
   buttons, profile menu, notification dropdown and plan badge had no styles at
   all because they never had any of their own. So §1 and §2 below are not
   "overrides" — they are the definitions the chrome has always assumed and this
   page must now supply. Everything is expressed in --ps-* tokens, which is why
   there is no light/dark duplication here: the tokens already resolve per theme.

   `!important` BUDGET: 2 rule sites, 3 declarations, all in §5, each with the
   exact declaration it is fighting written above it. Site (1) is one declaration
   fighting an inline `style` attribute emitted by the shared PHP, which nothing
   else in CSS can beat. Site (2) is two declarations (background-color + color)
   fighting a shared rule that is itself `!important`.

   Count them with comments stripped, or you will count the ones discussed in
   prose. There is a helper for exactly this, because writing the regex inline in
   a CSS comment does not work — the pattern contains a comment-close sequence,
   which ends the comment early and leaks the rest of this paragraph into the
   stylesheet, where the word above then counts as a fourth occurrence:

     sh persona-studio/tools/count-important.sh

   app.css and tokens.css are both 0 by that measure; this file is 3.

   The permanent fix for all of this is in includes/nav_functions.php +
   includes/footer_functions.php. This file should shrink to nothing the day the
   shared chrome owns its own tokens.
   ========================================================================== */


/* ==========================================================================
   1. THE VARIABLE BRIDGE
   Declared on the <body> element, not on :root, deliberately. The footer emits
   its own `:root { --footer-*: … }` block in a <style> INSIDE <body>, which is
   later in document order than this stylesheet and would therefore win a
   same-specificity fight. A custom property declared on <body> is resolved
   before inheritance ever reaches the footer, so proximity settles it and no
   !important is required.
   ========================================================================== */
.ps-body {
  /* --- nav + banner ---------------------------------------------------- */
  --bg-primary:           var(--ps-bg-deep);
  --surface-glass:        var(--ps-glass-tint);
  --surface-glass-hover:  var(--ps-overlay-hover);
  --border-glass:         var(--ps-glass-hairline);
  /* Opaque on purpose: a dropdown over the aurora needs a deterministic
     background or the text contrast inside it is a compositing accident. */
  --dropdown-bg:          var(--ps-surface-1);
  --text-primary:         var(--ps-text-1);
  --text-secondary:       var(--ps-text-2);
  --text-color:           var(--ps-text-1);
  --primary-color:        var(--ps-accent);
  --primary-color-dark:   var(--ps-accent-hover);
  --transition-speed:     var(--ps-dur-2);

  /* --- footer ---------------------------------------------------------- */
  /* The shared footer assumes white-on-dark: its own defaults are
     `--footer-text-primary: var(--text-color, #ffffff)` and
     `--footer-text-secondary: rgba(255,255,255,0.7)`, which on the light theme
     would be white text on a white panel. Re-pointed at the text ramp so the
     footer is legible in both themes. */
  --glass-background:       var(--ps-surface-1);
  --glass-background-hover: var(--ps-surface-1-hover);
  --footer-text-primary:    var(--ps-text-1);
  --footer-text-secondary:  var(--ps-text-2);
  --footer-border-color:    var(--ps-border);
  --footer-bg-hover:        var(--ps-surface-2);
  --footer-social-bg:       var(--ps-surface-2);
  --footer-social-bg-hover: var(--ps-surface-3);
}


/* ==========================================================================
   2. CHROME COMPONENTS WITH NO STYLES OF THEIR OWN
   /css/nav-shared.css styles the nav shell, the links, the dropdowns and the
   mobile menu. It has never styled `.button`, `.profile-*`, `.notification-*`
   or `.plan-badge` — those came from whichever page-level stylesheet happened
   to be loaded. On this page nothing does, so they are here.
   ========================================================================== */
.ps-body .auth-buttons { align-items: center; gap: var(--ps-s-2); }

.ps-body .button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ps-s-2);
  min-height: var(--ps-tap-min);
  min-width: var(--ps-tap-min);
  padding: var(--ps-s-2) var(--ps-s-4);
  border: var(--ps-bw) solid transparent;
  border-radius: var(--ps-r-control);
  color: var(--ps-text-1);
  font-family: var(--ps-font-sans);
  font-size: var(--ps-fs-sm);
  font-weight: var(--ps-fw-semibold);
  line-height: var(--ps-lh-normal);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--ps-t-base), border-color var(--ps-t-base), color var(--ps-t-base);
}
.ps-body .button-primary {
  background-color: var(--ps-accent);
  color: var(--ps-on-accent);
}
.ps-body .button-primary:hover { background-color: var(--ps-accent-hover); color: var(--ps-on-accent); }
.ps-body .button-outline {
  border-color: var(--ps-border-strong);
  background-color: transparent;
  color: var(--ps-text-2);
}
.ps-body .button-outline:hover { background-color: var(--ps-surface-2); color: var(--ps-text-1); }

/* Icon-only nav buttons: keep them square so the nav row does not go ragged. */
.ps-body .submit-icon,
.ps-body .notification-icon,
.ps-body .profile-icon { padding-inline: var(--ps-s-2); }

.ps-body .notification-wrapper { position: relative; }
.ps-body .notification-dropdown,
.ps-body .profile-menu {
  position: absolute;
  inset-inline-end: 0;
  inset-block-start: 100%;
  /* Above the nav (50) and above our docked sidebar (80), below our modal
     overlay (500). The shared sheet ships z-index 1000 on .nav-dropdown-menu,
     which would otherwise float a nav dropdown over an open dialog. */
  z-index: var(--ps-z-dropdown);
  display: none;
  min-inline-size: calc(var(--ps-sidebar-w) - var(--ps-s-6));
  max-inline-size: calc(100vw - var(--ps-s-8));
  margin-block-start: var(--ps-s-2);
  padding: var(--ps-s-2);
  border: var(--ps-bw) solid var(--ps-border);
  border-radius: var(--ps-r-3);
  background-color: var(--ps-surface-1);
  box-shadow: var(--ps-e-3);
}
/* The open state. BOTH class names are matched on purpose, because the shared
   chrome does not agree with itself:
     .show    js/notifications.js:69,79      (notification dropdown)
     .show    includes/nav_functions.php:1288 (profile menu)
     .active  js/nav.js:100                   (other shared menus)
   Verified by reading those files, not assumed.

   This block previously matched ONLY `.active`, which neither the bell nor the
   profile menu ever sets. The JS worked perfectly — the class was added,
   visibility went to visible and opacity to 1 — but `display` stayed `none`, so
   both buttons looked completely dead. The shared sheet animates these with
   opacity/visibility ONLY and never sets `display`, so introducing a `display`
   default here made this file responsible for the open state too. */
.ps-body .profile-menu.show,
.ps-body .profile-menu.active { display: block; }
/* flex, not block: css/notifications.css:120 declares the dropdown
   `display:flex; flex-direction:column` and lays out its header/list against
   that. Forcing `block` here silently changed its layout mode. */
.ps-body .notification-dropdown.show,
.ps-body .notification-dropdown.active { display: flex; flex-direction: column; }

/* ---------------------------------------------------------------------------
   Orphaned Font Awesome icons injected at RUNTIME by shared JS.

   partials/head.php drops Font Awesome (1.2% of its bytes were used) and
   ps_chrome_shim() rewrites `<i class="fas fa-*">` to our sprite — but the shim
   is a PHP string pass over render_navigation()/render_footer(), so it only sees
   server-rendered markup. It cannot reach icons that shared JS injects after
   load, and there are six:

     js/notifications.js:134  fa-bell-slash        (empty state)
     js/notifications.js:159  fa-arrow-right       (inline, in a link)
     js/notifications.js:255  fa-circle-notch spin (loading)
     js/notifications.js:264  fa-exclamation-circle(error)
     js/upgrade-modal.js      x2

   With the font gone these are not merely invisible, they still occupy space —
   and css/notifications.css:291 sizes the empty-state one at `font-size: 3rem`
   plus a 0.5rem margin and a 1rem flex gap. The result was a notification panel
   ~440px tall with "No notifications yet" stranded in the middle of a void.

   Collapsed rather than replaced: these are decorative next to text that already
   says the same thing ("No notifications yet", "View details"), and those files
   are shared site-wide, so this page must not edit them.
   --------------------------------------------------------------------------- */
.ps-body i[class*="fa-"] { display: none; }

/* With the 3rem glyph gone, the shared 4rem block padding is now just a hole. */
.ps-body .notification-empty { padding: var(--ps-s-7) var(--ps-s-5); gap: var(--ps-s-2); }

.ps-body .nav-dropdown-menu { z-index: var(--ps-z-dropdown); }

.ps-body .notification-header { padding: var(--ps-s-2) var(--ps-s-3); }
.ps-body .notification-header h4 { font-size: var(--ps-fs-sm); color: var(--ps-text-2); }
.ps-body .notification-list:empty::after {
  content: "Nothing new.";
  display: block;
  padding: var(--ps-s-3);
  color: var(--ps-text-3);
  font-size: var(--ps-fs-sm);
}

.ps-body .profile-email {
  padding: var(--ps-s-2) var(--ps-s-3);
  color: var(--ps-text-3);
  font-size: var(--ps-fs-xs);
  word-break: break-all;
}
.ps-body .profile-item {
  display: flex;
  align-items: center;
  gap: var(--ps-s-3);
  min-height: var(--ps-tap-min);
  padding: var(--ps-s-2) var(--ps-s-3);
  border-radius: var(--ps-r-2);
  color: var(--ps-text-2);
  font-size: var(--ps-fs-sm);
  text-decoration: none;
}
.ps-body .profile-item:hover { background-color: var(--ps-surface-2); color: var(--ps-text-1); }
.ps-body .profile-item.logout { color: var(--ps-error-text); }
.ps-body .profile-item.logout:hover { background-color: var(--ps-error-tint); color: var(--ps-error-text); }
.ps-body .profile-separator {
  margin-block: var(--ps-s-2);
  border: 0;
  border-top: var(--ps-bw) solid var(--ps-border);
}

.ps-body .plan-badge {
  display: inline-block;
  padding: var(--ps-s-h) var(--ps-s-2);
  border: var(--ps-bw) solid var(--ps-border-strong);
  border-radius: var(--ps-r-pill);
  background-color: var(--ps-surface-2);
  color: var(--ps-text-2);
  font-size: var(--ps-fs-2xs);
  font-weight: var(--ps-fw-semibold);
  letter-spacing: var(--ps-ls-label);
}
.ps-body .plan-badge.pro {
  border-color: var(--ps-warm-edge);
  background-color: var(--ps-warm-tint);
  color: var(--ps-warm-text);
}
.ps-body .plan-badge.basic {
  border-color: var(--ps-accent-edge);
  background-color: var(--ps-accent-tint);
  color: var(--ps-accent-text);
}

/* The shared nav's "Members" / upgrade link. */
.ps-body .nav-upgrade { color: var(--ps-warm-text); font-weight: var(--ps-fw-semibold); }

/* Icons injected into the chrome by ps_chrome_shim() are sized in em, because
   the same class lands in a 0.9rem nav link and in the upgrade modal's 2.6rem
   header. They only need to sit on the text baseline. */
.ps-body .ps-icon--chrome { vertical-align: middle; }


/* ==========================================================================
   3. LAYERING + ALIGNMENT: a shared nav above an app shell
   ========================================================================== */
/* The nav is position:sticky; top:0; z-index:50 and 64px tall (65 at >=1440
   with its border) — which is what --ps-nav-h holds, and what the docked
   sidebar's sticky offset is derived from. Nothing here hardcodes it. v1
   hardcoded `top: 64px` and `calc(100vh - 64px)` against a real nav bottom of
   207px, clipped its own logo, and grew a second scrollbar. */
.ps-body .nav-container { isolation: isolate; }

/* Align the nav's inner rail with the app shell's, so the logo sits over the
   sidebar rather than 60px inboard of it. nav-shared.css caps .nav-content at
   1280px; the shell measure is --ps-shell-max. */
.ps-body .nav-content {
  max-width: var(--ps-shell-max);
  padding-inline: var(--ps-s-4);
}
@media (min-width: 1024px) {
  .ps-body .nav-content { padding-inline: var(--ps-s-5); }
}
@media (min-width: 1600px) {
  .ps-body .nav-content { padding-inline: var(--ps-s-7); }
}

/* The shared mobile menu is a fixed panel at z-index 49. It must stay under our
   dialogs (600) and under the studio drawer (600) — it already does — but it
   also needs a real background now that --bg-primary resolves through us. */
.ps-body .mobile-menu {
  background-color: var(--ps-bg);
  border-inline-start: var(--ps-bw) solid var(--ps-border);
}
.ps-body .mobile-menu .nav-link,
.ps-body .mobile-menu .mobile-submenu-toggle { min-height: var(--ps-tap-min); }

/* Focus: the shared chrome has no :focus-visible treatment of its own, so it
   inherits the one from app.css §1. This only stops the ring being clipped by
   the nav's overflow. */
.ps-body .nav-link:focus-visible,
.ps-body .nav-dropdown-item:focus-visible,
.ps-body .button:focus-visible,
.ps-body .profile-item:focus-visible { outline-offset: 0; }


/* ==========================================================================
   4. FOOTER
   The footer styles itself from a <style> block in the body; it only needed the
   variables in §1. These are the two places where it hardcodes a colour that
   cannot survive a light background.
   ========================================================================== */
/* Fights: `.footer-links-section .footer-link-badge { color:#ffc107;
   background-color: rgba(255,193,7,.2) }` — 1.7:1 on the light footer panel.
   Won on specificity (0,3,0 vs 0,2,0), not with !important. */
.ps-body .footer-links-section .footer-link-badge {
  color: var(--ps-warm-text);
  background-color: var(--ps-warm-tint);
}
/* Fights: `.footer-links-section .footer-link-badge.badge-new { color:#22c55e;
   background-color: rgba(34,197,94,.15) }`. */
.ps-body .footer-links-section .footer-link-badge.badge-new {
  color: var(--ps-success-text);
  background-color: var(--ps-success-tint);
}

.ps-body .footer-v2 a:focus-visible,
.ps-body .footer-v2 button:focus-visible { outline-offset: var(--ps-focus-offset); }


/* ==========================================================================
   5. THE `!important`s — 2 sites, 3 declarations
   Each fights something no other CSS mechanism can reach: an inline `style`
   attribute written by the shared PHP, and a shared declaration that is itself
   !important. Nothing else in this file, and nothing at all in app.css.
   ========================================================================== */

/* (1) Fights the inline attribute emitted by includes/nav_functions.php on the
   Services link: style="color: #60a5fa; font-weight: 600". #60a5fa measures
   2.48:1 on the light theme's glass nav — an axe color-contrast failure that no
   selector can outrank, because it is an inline declaration. --ps-info-text is
   the same blue idea at a passing luminance in both themes. */
.ps-body .nav-links .nav-dropdown-toggle[style] { color: var(--ps-info-text) !important; }

/* (2) Fights `.newsletter-form-wrapper-v2 #newsletter-container input:focus {
   background-color: #000 !important }` in the shared footer's style block. On
   the light theme the input's colour is --footer-text-primary (near-black), so
   focusing the field made the user's own typing invisible. */
.ps-body .newsletter-form-wrapper-v2 #newsletter-container input:focus {
  background-color: var(--ps-sunken) !important;
  color: var(--ps-text-1) !important;
}
