/* =============================================================================
   Panelo — public (donor-facing) theme
   -----------------------------------------------------------------------------
   Sibling of ./panelo-panel.css, but a different substrate: the public pages do
   NOT run Metronic. They run a Skote build — Bootstrap 5.0.0-beta2 recompiled
   with primary #5b73e8, plus theme.min.css (topbar/topnav/footer chrome) and
   style.min.css (ribbons, cookie bar). Loaded from the one front layout:

     resources/views/front/layouts/app.blade.php

   which serves all four platforms and stamps data-platform on <body>. There is
   no dark theme here and there is not meant to be — these pages are permanently
   light, unlike the panel.

   Like the panel bundle, Skote compiles its palette to literal hex, so this
   overrides selectors rather than redefining variables. Where Bootstrap ships a
   utility with !important (.text-primary, .bg-primary, .border-primary,
   .text-muted) the override has to carry !important too.

   -------------------------------------------------------------- accent steps

     --pn-accent        #2EE6C5  bright aqua. Dark grounds and button fills that
                                 carry ink text. Never behind white text.
     --pn-accent-strong #12B39A  hover / pressed on dark grounds.
     --pn-accent-deep   #0E8C79  non-text use only here: borders, focus rings,
                                 icon strokes. 4.16:1 on white — fine for the
                                 3:1 non-text threshold, NOT fine for body text.
     --pn-accent-ink    #0C7A69  the step that carries text. 5.25:1 against
                                 white, 4.88:1 against the page canvas.

   The fourth step exists because these pages are read by a customer's visitors,
   not by staff. panelo-panel.css uses --pn-accent-deep behind white text and in
   .text-primary; measured, that pairing is 4.16:1 — under 4.5:1 either way
   round. Rather than ship the same shortfall to the public side, text and
   white-on-fill use --pn-accent-ink instead. The panel file is not mine to
   change; flagged separately.

   Mirrors ../panelo/brand/tokens.json for the three shared steps.

   ------------------------------------------------- per-platform brand fills

   The sign-in button on each front is painted in that network's own colour so a
   visitor recognises what they are about to hand over. These four hexes were
   inline `style="background: …"` on the buttons themselves; they are moved here
   unchanged, because the layout now knows which platform it is rendering.

   Measured against the white label Bootstrap's .btn-* gives them. Two of the
   four inline values failed AA and were darkened along their own hue:

     instagram  #7A47E9   5.38:1   unchanged
     google     #D13636   4.89:1   unchanged
     facebook   #2D86FF → #256ECF   3.52 → 4.99
     twitter    #2AA9E0 → #1D7396   2.68 → 5.32

   A sign-in button is the one control on the page a visitor must be able to
   read, and at 2.68:1 the Twitter one was a pale wash. Facebook's and Twitter's
   published blues cannot carry white text at 4.5:1 — a known property of both
   palettes, not something this app introduced — so the choice is a darker step
   of the same hue or a different text colour, and the hue is what makes the
   button recognisable. The exact values live in the token block below.
   ========================================================================== */

:root {
  --pn-accent: #2ee6c5;
  --pn-accent-strong: #12b39a;
  --pn-accent-deep: #0e8c79;
  --pn-accent-ink: #0c7a69;
  --pn-accent-dim: #0e3a36;
  --pn-accent-wash: #e6fbf6;

  /* Per-platform brand fills, each carrying white button text.
     Measured with the WCAG formula against #ffffff, never estimated:

       instagram #7A47E9  5.38:1   unchanged
       google    #D13636  4.89:1   unchanged
       facebook  #256ECF  4.99:1   was #2D86FF, 3.52:1 — failed
       twitter   #1D7396  5.32:1   was #2AA9E0, 2.68:1 — failed badly

     The two that failed are darker steps of the same hue, not different
     colours: Facebook's blue and Twitter's cyan at their published brightness
     cannot carry white text at 4.5:1, which is a well-known property of both
     palettes rather than anything this app did. The hue is what makes the
     button recognisable, and the hue is intact. */
  --pn-brand-instagram: #7a47e9;
  --pn-brand-facebook: #256ecf;
  --pn-brand-google: #d13636;
  --pn-brand-twitter: #1d7396;

  --pn-ink-950: #05080b;
  --pn-ink-900: #0a0f15;
  --pn-ink-800: #111922;
  --pn-ink-700: #1b2733;
  --pn-ink-500: #5f6b76;
  --pn-ink-400: #7d8fa1;

  --pn-surface: #ffffff;
  --pn-canvas: #f4f7f9;
  --pn-hairline: #e6ecf1;
}

/* ------------------------------------------------------------------- shell */

body {
  background-color: var(--pn-canvas);
}

/* Skote's dark topbar is #2f374e. Matched to the panel's dark chrome so the
   two halves of the product read as one brand. */
body[data-topbar="dark"] #page-topbar {
  background-color: var(--pn-ink-950);
  border-bottom: 1px solid var(--pn-ink-800);
  box-shadow: none;
}

body[data-topbar="dark"] .header-item {
  color: #e9ecef;
}

body[data-topbar="dark"] .header-item:hover {
  color: var(--pn-accent);
}

.navbar-brand-box {
  background-color: transparent;
}

.header-profile-user {
  border: 1px solid var(--pn-accent-deep);
}

/* --------------------------------------------------------- secondary navbar
   .topnav is the white service bar under the logo bar. Its default link colour
   is #7b8190 — 3.90:1 on white, under the 4.5:1 minimum for the nine service
   links, so it moves to --pn-ink-500 (5.07:1 on this ground). */

.topnav {
  background: var(--pn-surface);
  border-bottom: 1px solid var(--pn-hairline);
  box-shadow: none;
}

/* 13.5px was an inline <style> block in two of the four topnav copies, so the
   service bar was a different size on Instagram/Facebook than on
   YouTube/Twitter. One size, declared once. */
.topnav .navbar-nav .nav-link {
  color: var(--pn-ink-500);
  font-size: 13.5px;
}

.topnav .navbar-nav .nav-link:focus,
.topnav .navbar-nav .nav-link:hover {
  color: var(--pn-accent-ink);
  background-color: var(--pn-accent-wash);
}

.topnav .navbar-nav .nav-item .nav-link.active {
  color: var(--pn-accent-ink);
}

/* ----------------------------------------------------------------- accents */

/* Bright fill, ink label — the same trade the panel makes. The added border is
   new: #2EE6C5 against white is 1.59:1, so an unbordered aqua button has no
   discernible edge. --pn-accent-deep gives the shape a 4.16:1 boundary. */
.btn-primary,
.btn-primary.bg-gradient {
  background-color: var(--pn-accent);
  border-color: var(--pn-accent-deep);
  color: var(--pn-ink-950);
}

.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active,
.btn-primary.active,
.show > .btn-primary.dropdown-toggle {
  background-color: var(--pn-accent-strong);
  border-color: var(--pn-accent-ink);
  color: var(--pn-ink-950);
}

/* "Go to Service" — the main call to action on every service index. */
.btn-outline-primary {
  color: var(--pn-accent-ink);
  border-color: var(--pn-accent-deep);
}

.btn-outline-primary:hover,
.btn-outline-primary:active,
.btn-outline-primary.active,
.btn-outline-primary.dropdown-toggle.show {
  background-color: var(--pn-accent-ink);
  border-color: var(--pn-accent-ink);
  color: #fff;
}

.btn-check:focus + .btn-primary,
.btn-primary:focus,
.btn-check:focus + .btn-outline-primary,
.btn-outline-primary:focus {
  box-shadow: 0 0 0 0.15rem rgba(14, 140, 121, 0.35);
}

/* Bootstrap's click glow fires on mouse press too; keyboard users keep theirs
   through :focus-visible further down. */
.btn:focus:not(:focus-visible) {
  box-shadow: none;
}

/* ------------------------------------------------------- per-platform brand
   The sign-in control on each front. `data-platform` is stamped on <body> by
   the shared layout, which is what lets these live in a stylesheet at all —
   they used to be four inline style="" attributes on the buttons. */

body[data-platform="instagram"] .pn-brand-btn {
  background-color: var(--pn-brand-instagram);
  border-color: var(--pn-brand-instagram);
}

body[data-platform="facebook"] .pn-brand-btn {
  background-color: var(--pn-brand-facebook);
  border-color: var(--pn-brand-facebook);
}

body[data-platform="google"] .pn-brand-btn {
  background-color: var(--pn-brand-google);
  border-color: var(--pn-brand-google);
}

body[data-platform="twitter"] .pn-brand-btn {
  background-color: var(--pn-brand-twitter);
  border-color: var(--pn-brand-twitter);
}

/* These buttons also carry .bg-gradient, whose white wash is a background-image.
   The inline `background: #hex` shorthand they used to carry reset that image to
   none as a side effect; longhand background-color does not, so say it. Without
   this line the fills would come out lighter than they are today. */
.pn-brand-btn.bg-gradient {
  background-image: none;
}

/* Solid fills carrying white text use the ink step, never the deep one. */
.bg-primary {
  background-color: var(--pn-accent-ink) !important;
}

/* .bg-gradient lays a 15% white wash over the top of the fill, which drags
   white-on-primary from 5.25:1 down to 3.96:1. Dropped where it sits on a
   primary ground; it stays everywhere else. */
.bg-primary.bg-gradient {
  background-image: none !important;
}

.text-primary {
  color: var(--pn-accent-ink) !important;
}

.border-primary {
  border-color: var(--pn-accent-deep) !important;
}

a {
  color: var(--pn-accent-ink);
}

a:hover {
  color: var(--pn-accent-deep);
}

/* Skote's #74788d muted grey is 4.36:1 on white — just under. */
.text-muted {
  color: var(--pn-ink-500) !important;
}

/* ---------------------------------------------------------------- surfaces */

.card {
  border: 1px solid var(--pn-hairline);
  border-radius: 0.75rem;
  box-shadow: none;
}

.card-header {
  background-color: transparent;
  border-bottom: 1px solid var(--pn-hairline);
}

/* Skote rounds the header/footer to .25rem, which leaves a square shoulder
   inside the softer card corner wherever they carry a fill (the contact card's
   .bg-primary header, every .card-footer). */
.card > .card-header:first-child {
  border-radius: 0.75rem 0.75rem 0 0;
}

.card > .card-footer:last-child {
  border-radius: 0 0 0.75rem 0.75rem;
}

.card-footer {
  background-color: var(--pn-canvas);
  border-top: 1px solid var(--pn-hairline);
}

.card-text {
  color: var(--pn-ink-700);
}

.card hr {
  border-top-color: var(--pn-hairline);
  opacity: 1;
}

/* The availability ribbon. Red (unavailable) is left semantic; the green
   "available" flag joins the brand — at #0C7A69 the white glyph on it is
   5.25:1, where Skote's #1abc9c was 2.2:1. */
.ribbon.ribbon-success {
  background-color: var(--pn-accent-ink);
  background-image: linear-gradient(to bottom, var(--pn-accent-ink) 45%, #0a6558 100%);
}

.ribbon.ribbon-success:after,
.ribbon.ribbon-success:before {
  border-top-color: #0a6558;
}

/* ------------------------------------------------------------------- forms */

.form-control {
  border-color: #d5dee5;
  border-radius: 0.5rem;
  color: var(--pn-ink-800);
}

/* Skote clears the focus ring entirely (box-shadow:none, border #d3d8de), which
   left no way to tell which field is active. */
.form-control:focus,
.form-select:focus {
  border-color: var(--pn-accent-strong);
  box-shadow: 0 0 0 3px rgba(46, 230, 197, 0.28);
}

.form-control::placeholder {
  color: var(--pn-ink-500);
  opacity: 1;
}

.form-label {
  color: var(--pn-ink-700);
  font-weight: 500;
}

.form-check-input:checked {
  background-color: var(--pn-accent-ink);
  border-color: var(--pn-accent-ink);
}

/* Keyboard focus. The public pages had no visible state at all, same as the
   panel before its brand layer. */
:focus-visible {
  outline: 2px solid var(--pn-accent-deep);
  outline-offset: 2px;
}

.btn:focus-visible,
.nav-link:focus-visible,
.form-control:focus-visible {
  outline: 2px solid var(--pn-accent-deep);
  outline-offset: 2px;
}

/* On the near-black topbar the deep step would disappear, so the ring switches
   to the bright accent there — 12.66:1 against that ground. */
#page-topbar :focus-visible,
.cookiealert :focus-visible {
  outline-color: var(--pn-accent);
}

/* ------------------------------------------------------------------ footer */

.footer {
  background-color: var(--pn-surface);
  border-top: 1px solid var(--pn-hairline);
  box-shadow: none;
  color: var(--pn-ink-500);
}

/* -------------------------------------------------------------- cookie bar
   Dark ground, so the bright accent is legible here (12.12:1) — this is the one
   place on the public pages where it carries text. */

.cookiealert {
  background: var(--pn-ink-900);
  border-top: 1px solid var(--pn-accent-dim);
  color: #ecf0f1;
}

.cookiealert a {
  color: var(--pn-accent);
}

.cookiealert a:hover {
  color: #7ff2dd;
}

/* ------------------------------------------------------- speculative block
   The selectors below are emitted by front blades that need a logged-in donor
   session (the service, campaign and callback pages), so they could not be
   confirmed against rendered HTML. Restyles only — nothing here changes layout,
   and if a selector never matches, nothing happens. */

.badge.bg-primary {
  background-color: var(--pn-accent-ink) !important;
  color: #fff;
}

/* Skote's own badge fills carry white text and cannot hold it — measured against
   #fff: bg-danger #F46A6A = 2.95, bg-warning #F1B44C = 1.85. These badges are
   the *credit count*, the one number a visitor came to the page to read. Darker
   steps of the same hues: 6.54 and 6.39.

   The same fills also back the coloured card headers on the service pages
   (.bg-danger.bg-gradient.text-white measured 2.52), so the fill is corrected
   rather than only the badge. .bg-gradient lays a 15% white wash over the top,
   which is what dragged those under — dropped where it sits on these two. */
.badge.bg-danger,
.card-header.bg-danger,
.bg-danger {
  background-color: #b02a2a !important;  /* white text 6.54:1 */
}

.badge.bg-warning,
.card-header.bg-warning,
.bg-warning {
  background-color: #8a5200 !important;  /* white text 6.39:1 */
  color: #fff !important;
}

.bg-danger.bg-gradient,
.bg-warning.bg-gradient {
  background-image: none !important;
}

.progress-bar {
  background-color: var(--pn-accent-ink);
}

.table > :not(caption) > * > * {
  border-bottom-color: var(--pn-hairline);
}

.page-item.active .page-link {
  background-color: var(--pn-accent-ink);
  border-color: var(--pn-accent-ink);
  color: #fff;
}

.page-link {
  color: var(--pn-ink-700);
}

.page-link:hover {
  background-color: var(--pn-accent-wash);
  color: var(--pn-accent-ink);
}

.nav-pills .nav-link.active,
.nav-pills .show > .nav-link {
  background-color: var(--pn-accent-ink);
  color: #fff;
}

/* Counts of followers/likes sit in columns on the campaign pages. */
.countdown,
.counter-value {
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------ ajax spinner
   custom.js toggles #loading on every jQuery ajaxStart/ajaxStop, and custom.js
   loads on all four fronts — but only the YouTube layout carried the markup and
   this ~58-line rule set, inline in its <head>. The other three ran the global
   handler against an element that did not exist. The markup is now in the one
   shared layout and the styling is here. */

#loading {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  padding: 20% 0;
  text-align: center;
  background-color: var(--pn-surface);
  z-index: 9999;
}

.water {
  position: relative;
  width: 100px;
  height: 100px;
  margin: 0 auto;
  overflow: hidden;
  border-radius: 50%;
  background-color: var(--pn-accent);
  box-shadow:
    inset 0 0 30px 0 rgba(0, 0, 0, 0.5),
    0 4px 10px 0 rgba(0, 0, 0, 0.5);
}

.water::before,
.water::after {
  content: "";
  position: absolute;
  top: -150px;
  width: 400px;
  height: 400px;
  animation: pn-water-wave 5s linear infinite;
}

.water::before {
  border-radius: 45%;
  background: rgba(255, 255, 255, 0.7);
}

.water::after {
  border-radius: 35%;
  background: rgba(255, 255, 255, 0.3);
}

@keyframes pn-water-wave {
  0% {
    transform: rotate(0);
  }

  100% {
    transform: rotate(360deg);
  }
}

/* --------------------------------------------------------------------- a11y
   Skote animates the cookie bar in with a 0.5s translate and a 1s delay, and
   waves.js ripples every button. */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }

  .cookiealert,
  .cookiealert.show {
    transition-delay: 0s !important;
  }
}
