/* Copyright (c) 2026 PrepLocal. All rights reserved. */
/* PrepLocal's app typeface: Plus Jakarta Sans (SIL Open Font License,
   static/fonts/PlusJakartaSans-OFL.txt), served from this site rather than a
   font CDN, so no visitor's browser is sent to a third party to draw text.
   One variable file per character range covers every weight. Declaring it
   here costs nothing on pages that don't use it - a browser only downloads a
   font a page actually asks for (the landing page keeps its own). */
@font-face {
  font-family: "Plus Jakarta Sans";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("fonts/plus-jakarta-sans-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Plus Jakarta Sans";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("fonts/plus-jakarta-sans-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --pl-font: "Plus Jakarta Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --pl-font-display: var(--pl-font);
}

/* Day values of the shared theme (cobalt and white). theme.js takes these over
   on a page with <html data-pl-theme>, switching to night when the visitor
   picks Night mode; they are here so the page is still fully coloured before
   that runs, or if it never does. Keep in step with DAY and UI.day in theme.js.

   Colours are space-separated RGB triplets so a page can add its own alpha:
   rgb(var(--pl-wall-top) / 0.42). */
:root {
  --pl-body: 238 246 253;
  --pl-wall-top: 138 203 242;
  --pl-wall-mid: 225 239 252;
  --pl-wall-bottom: 210 232 250;
  --pl-corner-1: 74 127 212;
  --pl-corner-2: 138 203 242;
  --pl-stop-0: 255 255 255;
  --pl-stop-1: 245 250 254;
  --pl-stop-2: 238 246 253;
  --pl-stop-3: 217 234 250;
  --pl-heading-dark: 30 58 138;
  --pl-heading-light: 74 127 212;
  --pl-subtitle: 78 86 114;
  --pl-shine: 255 255 255;
  --pl-pill-0: 238 246 253;
  --pl-pill-1: 225 239 252;
  --pl-pill-2: 210 232 250;
  --pl-pill-text: 30 58 138;
  --pl-pill-hover-0: 138 203 242;
  --pl-pill-hover-1: 169 217 246;
  --pl-on-pill-hover: #0b1530;
  --pl-card-surface: 255 255 255;
  --pl-heading-shadow: rgba(30, 58, 138, 0.3);
  --pl-soft-shadow: rgba(30, 58, 138, 0.14);
  --pl-logo-shadow: rgba(31, 42, 74, 0.32);
  --pl-logo-night: 0;
  --pl-stars: 0;

  /* The kitchen drawings (templates/_kitchen_doodles.html) by day; theme.js
     lights them from the sky at night. */
  --pl-doodle-egg: #fff6e3;
  --pl-doodle-egg-line: #d9b35c;
  --pl-doodle-yolk: #f5a623;
  --pl-doodle-yolk-line: #d97c0b;
  --pl-doodle-pan: #8b95a5;
  --pl-doodle-pan-dark: #5b6675;
  --pl-doodle-pan-line: #cfd6e0;
  --pl-doodle-spatula: #3f9fd6;
  --pl-doodle-spatula-line: #1f6f9e;
  --pl-doodle-wood: #d9a15c;
  --pl-doodle-wood-dark: #9a6a34;
  --pl-doodle-wood-line: #7a5228;
  --pl-doodle-cloud: #ffffff;
  --pl-doodle-cloud-line: #9fb7a9;
  --pl-doodle-shadow: rgba(255, 255, 255, 0.7);
  --pl-doodle-opacity: 0.92;

  /* The everyday interface - cards, text, borders, inputs, links - as
     ready-to-use colours. theme.js keeps every text colour here readable on
     both the cards and the page around them. */
  --pl-surface: #ffffff;
  --pl-surface-glass: rgba(255, 255, 255, 0.9);
  --pl-ground-wash: rgba(255, 255, 255, 0.3);
  --pl-topbar: rgba(255, 255, 255, 0.9);
  --pl-ink: #1f2a4a;
  --pl-muted: #4e5672;
  --pl-faint: #677090;
  --pl-border: #c9ddf2;
  --pl-border-soft: #e1edf9;
  --pl-input: #ffffff;
  --pl-primary: #1e3a8a;
  --pl-primary-hover: #152961;
  --pl-primary-soft: rgba(30, 58, 138, 0.1);
  --pl-primary-focus: rgba(30, 58, 138, 0.22);
  --pl-on-primary: #ffffff;
  --pl-heading: #1e3a8a;
  --pl-card-heading-dark: #1e3a8a;
  --pl-card-heading-light: #4a7fd4;

  /* Status text (paid, pending, refunded...) drawn on a faint tint of
     itself: dark on the light cards, light on the dark ones. light-dark()
     follows the color-scheme theme.js sets as the cards switch. */
  --pl-ok: light-dark(#15803d, #86efac);
  --pl-warn: light-dark(#92400e, #fcd34d);
  --pl-info: light-dark(#1d4ed8, #93c5fd);
  --pl-neutral: light-dark(#4b5563, #cbd5e1);
  --pl-danger: light-dark(#b91c1c, #fca5a5);

  /* Chef's own warm clay, so its help stands apart from the blue buttons, and
     the text on it. */
  --pl-tier-chef: #b4461a;
  --pl-on-tier-chef: #ffffff;
}

/* Browsers without light-dark() keep the daytime status colours. */
@supports not (color: light-dark(#000, #fff)) {
  :root {
    --pl-ok: #15803d;
    --pl-warn: #92400e;
    --pl-info: #1d4ed8;
    --pl-neutral: #4b5563;
    --pl-danger: #b91c1c;
  }
}

/* The shared pieces every app page is built from (PR3, owner 21 Oct: "all
   info boxes, drop downs etc are all uniform"). Only this file says what a
   colour, a corner or a shadow is; pages use these names. A test fails on a
   colour typed anywhere else in the app (tests/test_theme_tokens.py). */
:root {
  /* Status as a fill - a badge, a dot, a button - behind white text: one
     shade each, dark enough for white by day and by night. Their faint
     tints (-soft) back a notice of that kind. */
  --pl-ok-fill: #15803d;
  --pl-warn-fill: #b45309;
  --pl-info-fill: #1d4ed8;
  --pl-danger-fill: #b91c1c;
  --pl-on-fill: #ffffff;
  --pl-ok-soft: color-mix(in srgb, var(--pl-ok) 8%, transparent);
  --pl-warn-soft: color-mix(in srgb, var(--pl-warn) 8%, transparent);
  --pl-info-soft: color-mix(in srgb, var(--pl-info) 8%, transparent);
  --pl-danger-soft: color-mix(in srgb, var(--pl-danger) 8%, transparent);

  /* Rewards' gold (stars, points) as words and marks; as a fill (a promo
     badge) one shade in both modes, with dark ink on it. */
  --pl-gold: light-dark(#a16207, #fcd34d);
  --pl-gold-soft: color-mix(in srgb, var(--pl-gold) 14%, transparent);
  --pl-gold-fill: #c9973f;
  --pl-on-gold: #2a1f08;

  /* Depth: a card resting on the page; a menu or pop-over above it; a
     dialog above everything; the page dimmed behind a dialog. --pl-shade is
     the one colour of every shadow (rgb(var(--pl-shade) / alpha)), as
     --pl-shine is of every light edge and shine. */
  --pl-shade: 16 28 45;
  --pl-shade-tint: 30 58 138;               /* the cobalt in a card's soft shadow */
  --pl-shadow-card: 0 1px 2px rgb(var(--pl-shade) / 0.05), 0 10px 28px -14px rgb(var(--pl-shade-tint) / 0.22);
  --pl-shadow-card-hover: 0 2px 4px rgb(var(--pl-shade) / 0.06), 0 16px 34px -14px rgb(var(--pl-shade-tint) / 0.3);
  --pl-shadow-pop: 0 12px 32px rgb(var(--pl-shade) / 0.18);
  --pl-shadow-dialog: 0 18px 50px rgb(var(--pl-shade) / 0.28);
  --pl-scrim: rgb(var(--pl-shade) / 0.42);

  /* Chef's mark (the knife): black everywhere, by day and by night (static/ask-chef.css). */
  --pl-chef-mark: #111111;

  /* Code and error text (Internal Tools > System status): light on dark in
     both modes, the way a terminal shows it. */
  --pl-code: #0f172a;
  --pl-on-code: #e2e8f0;

  /* Paper: white in both modes - behind a QR code, which scans dark on
     white, and the on-screen copy of a receipt or a sheet of labels, with
     the ink it's printed in. */
  --pl-paper: #ffffff;
  --pl-paper-ink: #1b2434;
  --pl-paper-muted: #545d6b;
  --pl-paper-rule: #cfd5de;

  /* A chart's pointer tip: dark in both modes, so it stands off any card;
     a refund on it in the night danger red. */
  --pl-tooltip: #111827;
  --pl-on-tooltip: #ffffff;
  --pl-tooltip-danger: #fca5a5;

  /* Charts: a sequential ramp in the cobalt hue, light to dark by day (more
     reads darker) and the other way at night (more reads lighter), so the
     most always stands out most from the card. Validated with the dataviz
     palette check: one hue, monotone lightness, visible steps, the light
     end at 2.27:1 on the day card and the dark end at 2.53:1 on the night
     card. --pl-viz-grid is the chart's rules. */
  --pl-viz-1: light-dark(#86aee8, #3a5fae);
  --pl-viz-2: light-dark(#5a8ad8, #5582cf);
  --pl-viz-3: light-dark(#3a67c0, #7fa6e6);
  --pl-viz-4: light-dark(#264c9a, #a9c8f5);
  --pl-viz-5: light-dark(#172f6b, #d6e6fb);
  --pl-viz-grid: light-dark(#e1edf9, #22356a);

  /* The logo mark's gloss and rim shade (login_landing.html), as triplets
     for rgb(var(--name) / alpha): its own artwork, the same by day and night. */
  --pl-logo-gloss: 255 255 255;
  --pl-logo-rim: 40 8 4;

  /* The photo cropper's stage (static/photo-crop.css): a dark checkerboard
     in both modes, so a photo is judged on neutral ground, with faint light
     guides on it. */
  --pl-photo-stage: #1b1f29;
  --pl-photo-stage-check: #232835;
  --pl-photo-guide: rgb(255 255 255 / 0.2);
  --pl-photo-edge: rgb(255 255 255 / 0.12);

  /* Internal Tools > Calendar: a colour for each area of the business. */
  --pl-ops-server: light-dark(#1f5f8b, #93c5fd);
  --pl-ops-database: light-dark(#5b3f94, #c4b5fd);
  --pl-ops-security: light-dark(#a52a1c, #fca5a5);
  --pl-ops-business: light-dark(#9c2f6e, #f9a8d4);

  /* The calendar's kinds of thing (static/events.css). Four hues that stay
     apart from each other for colour-blind readers in both modes, every pair
     checked with the dataviz palette check against the day card (#ffffff)
     and the night card (#14224a); blue is left out so no kind blends with
     the cobalt buttons or today's filled day. Offers and menu changes share
     a quiet grey. */
  --pl-kind-event: light-dark(#e87ba4, #d55181);
  --pl-kind-holiday: light-dark(#6250d6, #9085e9);
  --pl-kind-message: #008300;
  --pl-kind-own: light-dark(#eda100, #c98500);
  --pl-kind-other: #898781;

  /* Corners: small (a text box, a button, a notice), medium (a card, a
     menu), large (a dialog, a panel), extra large (a page's one big card,
     like the sign-in card, and Chef's message box - round on one line,
     gentle as it grows), and a pill (only on something one line tall: a
     tall box with a pill corner is an oval). */
  --pl-radius-sm: 8px;
  --pl-radius-md: 12px;
  --pl-radius-lg: 16px;
  --pl-radius-xl: 24px;
  --pl-radius-pill: 999px;
}
@supports not (color: light-dark(#000, #fff)) {
  :root { --pl-gold: #a16207; --pl-kind-event: #e87ba4; --pl-kind-holiday: #6250d6; --pl-kind-own: #eda100;
          --pl-ops-server: #1f5f8b; --pl-ops-database: #5b3f94; --pl-ops-security: #a52a1c; --pl-ops-business: #9c2f6e;
          --pl-viz-1: #86aee8; --pl-viz-2: #5a8ad8; --pl-viz-3: #3a67c0; --pl-viz-4: #264c9a; --pl-viz-5: #172f6b;
          --pl-viz-grid: #e1edf9; }
}

/* The short names the app's pages were written with - each one of the
   theme's colours above. Defined here and nowhere else, so the console,
   Internal Tools, customer and sign-in pages can't drift apart. */
:root {
  --text: var(--pl-ink);
  --muted: var(--pl-muted);
  --faint: var(--pl-faint);
  --border: var(--pl-border);
  --border-soft: var(--pl-border-soft);
  --primary: var(--pl-primary);
  --primary-hover: var(--pl-primary-hover);
  --primary-soft: var(--pl-primary-soft);
  --primary-focus: var(--pl-primary-focus);
  --heading-accent: var(--pl-heading);
  --card: var(--pl-surface-glass);
  --surface: var(--pl-surface-glass);
  --surface-solid: var(--pl-surface);
  --surface-sunk: color-mix(in srgb, var(--pl-surface) 94%, var(--pl-ink));
  --ok: var(--pl-ok);
  --check-green: var(--pl-ok);
  --warn: var(--pl-warn);
  --error: var(--pl-danger);
  --gold: var(--pl-gold);
  --gold-soft: var(--pl-gold-soft);
  --shadow: var(--pl-shadow-card);
  --radius: var(--pl-radius-md);
}

/* A notice: the message after an action (a flash, static/ui-dialog.css adds
   its icon) or one inside a page - an error under a form, "saved", a warning,
   a tip. One look for every page, day and night: the words in the page's own
   ink, which reads best; the kind in the left edge and a faint wash of it.
     <p class="pl-note is-danger">...</p>   is-ok, is-warn, is-info; none = a plain note */
.pl-note,
.flash {
  margin: 0 0 12px;
  padding: 11px 14px;
  border: 1px solid var(--pl-border);
  border-left: 3px solid var(--pl-primary);
  border-radius: var(--pl-radius-sm);
  background: var(--pl-primary-soft);
  color: var(--pl-ink);
  font-size: 0.85rem;
  font-weight: 500;
  line-height: 1.45;
}
/* The edge in the status colour that reads on the card, by day and by night. */
.pl-note.is-ok, .flash-success { border-left-color: var(--pl-ok); background: var(--pl-ok-soft); }
.pl-note.is-warn, .flash-warning { border-left-color: var(--pl-warn); background: var(--pl-warn-soft); }
.pl-note.is-danger, .flash-error { border-left-color: var(--pl-danger); background: var(--pl-danger-soft); }
.pl-note.is-info { border-left-color: var(--pl-info); background: var(--pl-info-soft); }
/* A quiet note: an aside (what a report leaves out, a placeholder) in muted words. */
.pl-note.is-quiet { border-left-color: var(--pl-faint); background: var(--pl-surface); color: var(--pl-muted); }
.pl-note a { color: var(--pl-primary); font-weight: 600; }

/* A card: a box of related things on a page, the same surface, edge, corner
   and resting shadow on every page; a tile is a smaller card in a grid (a
   figure, a choice). A page adds its own class beside it for what's inside:
     <section class="pl-card camp-card">...</section> */
.pl-card,
.pl-tile {
  margin: 0 0 16px;
  padding: 16px 18px;
  background: var(--pl-surface-glass);
  border: 1px solid var(--pl-border);
  border-radius: var(--pl-radius-md);
  box-shadow: var(--pl-shadow-card);
}
.pl-tile { margin: 0; padding: 14px 16px; }
@media print { .pl-card, .pl-tile { box-shadow: none; } }

/* Nothing here yet: a list or a page with nothing in it - centred, muted,
   in a dashed box so it reads as the place things will go. */
.pl-empty {
  margin: 0;
  padding: 20px 16px;
  border: 1px dashed var(--pl-border);
  border-radius: var(--pl-radius-md);
  color: var(--pl-muted);
  font-size: 0.88rem;
  line-height: 1.5;
  text-align: center;
}

/* Form fields a page leaves to the browser's defaults look like every other
   text box in the app - the theme's input colours (none left in the
   browser's own grey at night), its border, corners, type and focus ring.
   Zero specificity, so any rule a page does set still wins. */
:where([data-pl-theme]) :where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"],
                                        [type="file"], [type="submit"], [type="button"], [type="image"],
                                        [type="reset"], [type="hidden"]),
                               textarea, select) {
  box-sizing: border-box;
  min-height: 36px;
  padding: 6px 11px;
  border: 1px solid var(--pl-border);
  border-radius: var(--pl-radius-sm);
  background-color: var(--pl-input);
  color: var(--pl-ink);
  font: inherit;
  font-size: 0.87rem;
  line-height: 1.35;
}
:where([data-pl-theme]) :where(textarea) {
  padding: 8px 11px;
}
:where([data-pl-theme]) :where(input, textarea, select)::placeholder {
  color: var(--pl-faint);
  opacity: 1;
}
:where([data-pl-theme]) :where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"],
                                        [type="file"], [type="submit"], [type="button"], [type="image"]),
                               textarea, select):focus-visible {
  outline: none;
  border-color: var(--pl-primary);
  box-shadow: 0 0 0 3px var(--pl-primary-soft);
}
/* A file box never runs past its space: it shrinks, trimming the file's
   name, rather than push a small phone's page sideways. */
:where([data-pl-theme]) :where(input[type="file"]) {
  min-width: 0;
  max-width: 100%;
}

/* Every form fits on a phone (owner's QA, 2026-10-24, Marketing > Website pop-up):
   - The file picker's button is the theme's quiet button, never the browser's grey "Choose File".
   - A date or time box shrinks to its space like any other: iPhone's Safari draws them at a fixed width of
     their own, which ran From and Until into each other and past the card. Its value reads from the left.
   - A field in a row of fields can be narrower than its words: a grid or flex child gives way rather than
     pushing its neighbours (or the page) wider.
   The release check measures every Owner Console page on a phone for all three
   (release_check/run.py, FORM_FIT). */
:where([data-pl-theme]) :where(input[type="file"])::file-selector-button {
  margin-right: 10px;
  padding: 7px 12px;
  border: 1px solid var(--pl-border);
  border-radius: var(--pl-radius-sm);
  background: var(--pl-surface);
  color: var(--pl-primary);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
:where([data-pl-theme]) :where(input[type="file"])::file-selector-button:hover {
  border-color: var(--pl-primary);
  background: var(--pl-primary-soft);
}
:where([data-pl-theme]) :where(input[type="date"], input[type="time"], input[type="datetime-local"],
                               input[type="month"]) {
  -webkit-appearance: none;
  appearance: none;
  min-width: 0;
  max-width: 100%;
}
:where([data-pl-theme]) :where(input[type="date"], input[type="time"], input[type="datetime-local"],
                               input[type="month"])::-webkit-date-and-time-value {
  text-align: left;
}
:where([data-pl-theme]) :where(label:has(> input, > select, > textarea)) {
  min-width: 0;
}

/* The PrepLocal teardrop in the theme's colours: the night pin over the day
   one, shown in night mode - see prep_logo() in _prep_logo.html. */
.pl-logo {
  position: relative;
  display: inline-block;
  flex: none;
}
.pl-logo img {
  display: block;
  width: 100%;
  height: 100%;
}
.pl-logo img + img {
  position: absolute;
  inset: 0;
}
.pl-logo .pl-logo-night { opacity: var(--pl-logo-night); }

/* The sky behind a themed page, with its stars - the landing page's
   background, reusable anywhere:
     <div class="pl-sky" aria-hidden="true">
       <div class="pl-stars"><span></span><span></span></div>
     </div>
   placed first inside <body>. It sits behind everything (z-index -1), so the
   page's own layout is untouched. `is-soft` lays a wash of the card colour
   over it for busier pages whose text sits straight on the background. */
.pl-sky {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(ellipse 1500px 340px at 50% 4%, rgb(var(--pl-wall-top) / 0.6), transparent 68%),
    radial-gradient(ellipse 1500px 340px at 50% 34%, rgb(var(--pl-wall-mid) / 0.5), transparent 70%),
    radial-gradient(ellipse 1600px 360px at 50% 96%, rgb(var(--pl-wall-bottom) / 0.55), transparent 70%),
    radial-gradient(circle at 86% 14%, rgb(var(--pl-corner-1) / 0.24), transparent 28%),
    radial-gradient(circle at 16% 84%, rgb(var(--pl-corner-2) / 0.4), transparent 30%),
    linear-gradient(180deg, rgb(var(--pl-stop-0)) 0%, rgb(var(--pl-stop-1)) 40%, rgb(var(--pl-stop-2)) 72%, rgb(var(--pl-stop-3)) 100%);
}

.pl-sky.is-soft::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--pl-ground-wash);
}

/* The night sky: two star fields that fade in as it gets dark (--pl-stars
   follows the night, so they are gone by day) and twinkle out of step with
   each other. Drawn as inline SVG tiles, so there is nothing to fetch. Put
   <div class="pl-stars" aria-hidden="true"><span></span><span></span></div>
   inside a page's background layer, before anything that should sit over it. */
.pl-stars {
  position: absolute;
  inset: 0;
  opacity: var(--pl-stars);
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 40%, transparent 78%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 40%, transparent 78%);
}

.pl-stars span {
  position: absolute;
  inset: 0;
}

.pl-stars span:first-child {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='640' height='420'%3E%3Ccircle cx='209' cy='66' r='1.1' fill='%23fff' fill-opacity='0.49'/%3E%3Ccircle cx='343' cy='155' r='0.6' fill='%23fff' fill-opacity='0.73'/%3E%3Ccircle cx='28' cy='183' r='0.6' fill='%23fff' fill-opacity='0.50'/%3E%3Ccircle cx='272' cy='345' r='0.7' fill='%23fff' fill-opacity='0.57'/%3E%3Ccircle cx='401' cy='394' r='1.0' fill='%23fff' fill-opacity='0.67'/%3E%3Ccircle cx='621' cy='23' r='1.2' fill='%23fff' fill-opacity='0.61'/%3E%3Ccircle cx='95' cy='53' r='0.8' fill='%23fff' fill-opacity='0.90'/%3E%3Ccircle cx='118' cy='244' r='1.0' fill='%23fff' fill-opacity='0.65'/%3E%3Ccircle cx='350' cy='30' r='0.6' fill='%23fff' fill-opacity='0.56'/%3E%3Ccircle cx='434' cy='180' r='0.8' fill='%23fff' fill-opacity='0.77'/%3E%3Ccircle cx='290' cy='128' r='1.2' fill='%23fff' fill-opacity='0.83'/%3E%3Ccircle cx='158' cy='241' r='1.0' fill='%23fff' fill-opacity='0.93'/%3E%3Ccircle cx='465' cy='123' r='1.3' fill='%23fff' fill-opacity='0.51'/%3E%3Ccircle cx='268' cy='316' r='0.7' fill='%23fff' fill-opacity='0.72'/%3E%3Ccircle cx='29' cy='279' r='1.1' fill='%23fff' fill-opacity='0.77'/%3E%3Ccircle cx='557' cy='133' r='1.1' fill='%23fff' fill-opacity='0.78'/%3E%3Ccircle cx='370' cy='192' r='1.2' fill='%23fff' fill-opacity='0.97'/%3E%3Ccircle cx='304' cy='278' r='0.6' fill='%23fff' fill-opacity='0.84'/%3E%3Ccircle cx='413' cy='413' r='1.2' fill='%23fff' fill-opacity='0.61'/%3E%3Ccircle cx='248' cy='279' r='0.6' fill='%23fff' fill-opacity='0.70'/%3E%3Ccircle cx='110' cy='52' r='0.6' fill='%23fff' fill-opacity='0.87'/%3E%3Ccircle cx='86' cy='106' r='0.9' fill='%23fff' fill-opacity='0.93'/%3E%3Ccircle cx='55' cy='189' r='1.0' fill='%23fff' fill-opacity='0.94'/%3E%3Ccircle cx='522' cy='360' r='0.8' fill='%23fff' fill-opacity='0.68'/%3E%3Ccircle cx='231' cy='368' r='1.3' fill='%23fff' fill-opacity='0.53'/%3E%3Ccircle cx='115' cy='100' r='0.8' fill='%23fff' fill-opacity='0.72'/%3E%3Ccircle cx='376' cy='112' r='0.6' fill='%23fff' fill-opacity='0.68'/%3E%3Ccircle cx='237' cy='237' r='1.3' fill='%23fff' fill-opacity='0.83'/%3E%3Ccircle cx='330' cy='258' r='1.1' fill='%23fff' fill-opacity='0.48'/%3E%3Ccircle cx='573' cy='325' r='1.2' fill='%23fff' fill-opacity='0.89'/%3E%3Ccircle cx='252' cy='168' r='0.7' fill='%23fff' fill-opacity='0.80'/%3E%3Ccircle cx='43' cy='32' r='0.7' fill='%23fff' fill-opacity='0.54'/%3E%3Ccircle cx='219' cy='26' r='0.6' fill='%23fff' fill-opacity='0.53'/%3E%3Ccircle cx='68' cy='154' r='0.6' fill='%23fff' fill-opacity='0.93'/%3E%3C/svg%3E");
  animation: pl-twinkle 4.5s ease-in-out infinite;
}

.pl-stars span:last-child {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='520' height='360'%3E%3Ccircle cx='351' cy='280' r='1.3' fill='%23fff' fill-opacity='0.73'/%3E%3Ccircle cx='205' cy='355' r='1.1' fill='%23fff' fill-opacity='0.53'/%3E%3Ccircle cx='138' cy='96' r='1.2' fill='%23fff' fill-opacity='0.60'/%3E%3Ccircle cx='59' cy='119' r='1.1' fill='%23fff' fill-opacity='0.76'/%3E%3Ccircle cx='107' cy='29' r='1.1' fill='%23fff' fill-opacity='0.75'/%3E%3Ccircle cx='203' cy='262' r='1.5' fill='%23fff' fill-opacity='0.68'/%3E%3Ccircle cx='55' cy='260' r='1.5' fill='%23fff' fill-opacity='0.67'/%3E%3Ccircle cx='341' cy='109' r='1.6' fill='%23fff' fill-opacity='0.91'/%3E%3Ccircle cx='409' cy='340' r='1.1' fill='%23fff' fill-opacity='0.75'/%3E%3Ccircle cx='378' cy='286' r='1.2' fill='%23fff' fill-opacity='0.53'/%3E%3Ccircle cx='325' cy='41' r='1.5' fill='%23fff' fill-opacity='0.45'/%3E%3Ccircle cx='237' cy='173' r='1.0' fill='%23fff' fill-opacity='0.71'/%3E%3Ccircle cx='260' cy='134' r='1.6' fill='%23fff' fill-opacity='0.93'/%3E%3Ccircle cx='460' cy='90' r='0.9' fill='%23fff' fill-opacity='0.66'/%3E%3Ccircle cx='62' cy='252' r='1.1' fill='%23fff' fill-opacity='0.52'/%3E%3Ccircle cx='149' cy='146' r='1.5' fill='%23fff' fill-opacity='0.70'/%3E%3Cpath d='M165 233Q165 237 169 237Q165 237 165 241Q165 237 160 237Q165 237 165 233Z' fill='%23fff8e6'/%3E%3Cpath d='M120 234Q120 240 126 240Q120 240 120 245Q120 240 115 240Q120 240 120 234Z' fill='%23fff8e6'/%3E%3Cpath d='M69 36Q69 41 74 41Q69 41 69 46Q69 41 64 41Q69 41 69 36Z' fill='%23fff8e6'/%3E%3C/svg%3E");
  background-position: 170px 90px;
  animation: pl-twinkle 6.5s ease-in-out infinite 1.8s;
}

@keyframes pl-twinkle {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}

@media (prefers-reduced-motion: reduce) {
  .pl-stars span { animation: none; }
}

/* Night mode: the button that switches between the day and night palettes
   (templates/_theme_toggle.html). theme.js marks the page data-pl-mode
   before it paints, so the right icon and words show from the start: a moon
   and "Night mode" by day, a sun and "Day mode" by night. */
.pl-night-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 0 11px 0 9px;
  border: 1px solid var(--pl-border);
  border-radius: 999px;
  background: transparent;
  color: var(--pl-muted);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: color 140ms ease, border-color 140ms ease, background 140ms ease;
}
.pl-night-toggle:hover { color: var(--pl-primary); border-color: var(--pl-primary); }
.pl-night-toggle:focus-visible { outline: 2px solid var(--pl-primary); outline-offset: 2px; }
.pl-night-sun,
.pl-night-off,
[data-pl-mode="night"] .pl-night-moon,
[data-pl-mode="night"] .pl-night-on { display: none; }
[data-pl-mode="night"] .pl-night-sun { display: inline; }
[data-pl-mode="night"] .pl-night-off { display: inline; }
@media (max-width: 640px) {
  .pl-night-toggle { width: 34px; min-height: 34px; padding: 0; justify-content: center; }
  /* Icon only on a phone; the words stay for screen readers. */
  .pl-night-label {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
  }
}
/* The initials menu (C20, templates/_topbar_me.html): the signed-in
   person's initials as a round button at the end of a top bar, opening a
   small menu with who they are, Log out, and - on a phone - whatever the
   bar moved in to make room (.pl-top-wide stays out on a computer,
   .pl-top-narrow shows in the menu on a phone). Internal Tools' bar and
   the owner console's share it; static/topbar-menu.js closes it. */
.pl-me { position: relative; }
.pl-me > summary { list-style: none; }
.pl-me > summary::-webkit-details-marker { display: none; }
.pl-initials {
  display: inline-grid; place-items: center; width: 36px; height: 36px;
  border: 1px solid var(--pl-border); border-radius: 50%;
  background: var(--pl-primary); color: var(--pl-on-primary);
  font-size: 0.78rem; font-weight: 700; letter-spacing: 0.04em; cursor: pointer; user-select: none;
}
.pl-initials:hover { filter: brightness(1.08); }
.pl-initials:focus-visible { outline: 2px solid var(--pl-primary); outline-offset: 2px; }
.pl-menu {
  position: absolute; z-index: 60; top: calc(100% + 8px); right: 0; min-width: 220px; padding: 6px;
  background: var(--pl-surface); border: 1px solid var(--pl-border);
  border-radius: var(--pl-radius-md); box-shadow: var(--pl-shadow-pop);
}
.pl-who { display: grid; gap: 1px; margin: 0; padding: 8px 10px 10px; border-bottom: 1px solid var(--pl-border); font-size: 0.86rem; }
.pl-who span { color: var(--pl-muted); font-size: 0.78rem; }
.pl-menu-item { display: flex; align-items: center; margin: 0; padding: 8px 10px; border-radius: var(--pl-radius-sm); color: var(--pl-text); font-size: 0.86rem; font-weight: 600; text-decoration: none; }
a.pl-menu-item:hover, a.pl-menu-item:focus-visible { background: var(--pl-primary-soft); color: var(--pl-primary); }
.pl-menu-item .pl-night-toggle { width: auto; min-height: 0; padding: 0; border: 0; font: inherit; color: inherit; }
/* In the menu the toggle keeps its words on a phone (the rule above shows the icon alone there). */
.pl-menu-item .pl-night-label { position: static; width: auto; height: auto; overflow: visible; clip-path: none; }
.pl-logout { padding: 0; border: 0; background: none; font: inherit; color: var(--pl-danger); cursor: pointer; }
.pl-logout:hover { text-decoration: underline; }
.pl-top-narrow { display: none; }
@media (max-width: 640px) {
  .pl-top-wide { display: none; }
  .pl-top-narrow { display: flex; }
}

/* The "Viewing as ..." bar PrepLocal Internal sees while impersonating
   (templates/_impersonation_banner.html). Deliberately not themed: it has to
   stand out on every page, day or night, as a warning that this is
   someone else's account. */
.pl-impersonating {
  position: sticky; top: 0; z-index: 40; display: flex; flex-wrap: wrap; align-items: center;
  justify-content: center; gap: 8px 14px; padding: 8px 16px; background: #7c2d12; color: #fff;
  font-size: 0.83rem; font-weight: 600;
}
.pl-impersonating form { margin: 0; }
.pl-impersonating button {
  padding: 4px 12px; border: 1px solid rgba(255, 255, 255, 0.5); border-radius: 999px;
  background: transparent; color: #fff; font: inherit; font-weight: 700; cursor: pointer;
}
.pl-impersonating button:hover { background: rgba(255, 255, 255, 0.12); }
