/*==============================================================*
 *                           CSS MAP
 *==============================================================*
 *
 *  1) DESIGN TOKENS (ROOT VARIABLES)
 *     - global variables used everywhere
 *     - JS can overwrite some of these at runtime
 *
 *  2) DOCUMENT BASE + BACKGROUND
 *     - html/body scroll ownership (JS swaps this)
 *     - base typography + background color safety
 *
 *  3) CANVAS LAYER
 *     - #constellations fixed full-screen
 *     - background image lives here
 *
 *  4) PAGE STRUCTURE + TYPOGRAPHY
 *     - spacing and text sizing rules
 *     - divider styling (hr + .divider)
 *
 *  5) CONTENT CONTAINERS
 *     - article layout + [hidden] behavior
 *
 *  6) LINKS
 *     - base link style + hover effects
 *
 *  7) IMAGES
 *     - circular avatars
 *
 *  8) BUTTONS
 *     - glass pills, hover behavior, and button icons
 *
 *  9) HEADER
 *     - logo, title, tagline, and the labeled nav buttons
 *
 * 10) SLIDE-IN PAGE TRANSITION SYSTEM
 *     - #transitionContainer and JS-driven states
 *     - .homeJs / .otherJs / .noJs
 *
 * 11) REDUCED-MOTION ACCESSIBILITY
 *     - disables animated canvas + transitions when requested
 *
 * 12) FORM ELEMENTS (LOGIN/REGISTER), CHECKBOXES, PILL SWITCHES
 *
 * 13) GRADIENT BORDERS
 *
 * 14) DATE BOXES AND THE CALENDAR THAT PICKS A DAY
 *
 * 15) FLOATING CARDS
 *
 *  Themes (Settings: Prismal, Professional, Dark, Spooky, Elements, Poison, Blue, Fall, Winter, Festive, Floral, Digital, Love, Clovers, Playful, Mechanical)
 *  are in themes.css: each one sets the tokens in section 1 again, and changes a few rules of its own (its header lists
 *  everything a new theme needs).
 *
 *  NOTE: Sections use /* #region ... *\/ for editor folding.
 *==============================================================*/


/* #region 1) DESIGN TOKENS (ROOT VARIABLES) */
/*========================================*
 *  1) DESIGN TOKENS (ROOT VARIABLES)
 *========================================*
 *  The site's shared values, used everywhere else with var(--NAME). Layout.js sets the slide
 *  distance for each page transition.
 */

:root {
  /* Page slides (Layout.js sets the distance for each transition) */
  --SLIDE_DISTANCE: 100vh;
  --SLIDE_DURATION: 0.6s;

  /* The red glow on chosen controls */
  --SHADOW: 0 0 20px rgba(var(--PICK_RGB), 1);
  --PICK_SHADOW: 0 0 16px rgba(var(--PICK_RGB), 0.75);
  /* A button under the pointer: a soft blue-violet glow around its brighter edge */
  --HOVER_SHADOW: 0 0 12px rgba(var(--GLOW_RGB), 0.55);

  /* Brand colors: links, and text (body text, titles and dates, and labels and hints) */
  --LINK_LIGHT: #ee0000;
  --LINK_DARK:  #550000;
  --BASE_COLOR: #c9cce4;
  --TEXT_BRIGHT: #f2f3ff;
  --TEXT_DIM: #9297bd;

  /* Neon accents */
  --NEON_BLUE: #4f7bff;
  --NEON_VIOLET: #8d5cff;
  --NEON_CYAN: #46c8ff;
  --NEON_PINK: #e050ff;
  --TITLE_GLOW: 0 0 14px rgba(var(--GLOW_RGB), 0.45);

  /* Glass: the cards, tabs, and buttons the page sits on, over the starfield (see-through enough for the stars, dark
     enough to read on). Its edge is a faint blue line. */
  --GLASS: linear-gradient(180deg, rgba(24, 26, 70, 0.84), rgba(11, 11, 36, 0.88));
  --GLASS_BUTTON: rgba(18, 20, 56, 0.72);
  --GLASS_LINE: rgba(128, 140, 255, 0.24);
  --GLASS_LINE_BRIGHT: rgba(150, 165, 255, 0.45);
  --GLASS_SHADOW: 0 10px 28px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.06);
  --GLASS_RADIUS: 16px;

  /* Glowing things (the page that's showing, today on the calendar, Quick Entry): a blue-violet radial gradient from
     their center, a bright edge, and a glow around them */
  --GLOW_FILL: radial-gradient(ellipse at center, rgba(104, 124, 255, 0.55) 0%, rgba(92, 64, 235, 0.3) 45%, rgba(40, 24, 130, 0.12) 75%, rgba(20, 16, 70, 0.05) 100%);
  --GLOW_EDGE: rgba(150, 165, 255, 0.9);
  --GLOW_SHADOW: 0 0 16px rgba(var(--GLOW_RGB), 0.55), inset 0 0 12px rgba(var(--GLOW_RGB), 0.25);

  /* What a recommended button (Save, Add Entry, Sign In) is filled with, under --GLOW_FILL: it glows like Quick Entry */
  --RECOMMENDED_FILL: linear-gradient(90deg, rgba(40, 70, 210, 0.55), rgba(130, 50, 220, 0.55));
  /* A button that's not recommended (Delete, Sign Out Everywhere), and one that can't be used now: darker (the first with
     muted red words) */
  --DARK_BUTTON: rgba(6, 7, 22, 0.88);
  --DANGER_TEXT: #d98a94;

  /* Chosen buttons (a picked refraction type or account, Cost or Gain, an open date picker's button): the red-orange
     gradient border and red glow, over a red radial gradient from their center (see GRADIENT BORDERS at the end) */
  --PICK_FILL: radial-gradient(ellipse at center, rgba(255, 96, 40, 0.42) 0%, rgba(214, 24, 24, 0.22) 50%, rgba(120, 0, 30, 0.08) 85%, transparent 100%);

  /* How wide the page's content gets */
  --PAGE_WIDTH: min(94vw, 1200px);

  /* Transition speeds, shared so every control moves the same way */
  --SLOW_TRANSFORM: 0.3s ease-out;
  --SLOW_BORDER:    0.3s ease-out;
  --SLOW_SHADOW:    0.7s ease-out;
  --SLOW_COLOR:     0.5s ease-out;

  /* Placeholders */
  --PLACEHOLDER_COLOR: rgba(90, 90, 90, 0.5);

  /* The red-orange diagonal gradient on the borders of chosen controls (see GRADIENT BORDERS at the end) */
  --EDGE_GRADIENT: linear-gradient(135deg, #ee0000 0%, #ff4500 55%, #ff9a1a 100%);

  /* Floating windows (panels, Search, Help, the date picker): deep violet to navy glass */
  --HOVER_GRADIENT: linear-gradient(160deg, rgba(40, 26, 108, 0.98) 0%, rgba(24, 20, 84, 0.98) 48%, rgba(12, 18, 64, 0.98) 100%);
  --FLOAT_SHADOW: 0 16px 40px rgba(var(--SHADE_RGB), 0.7), 0 0 26px rgba(var(--GLOW_RGB), 0.28);

  /* How a day looks (Home's calendar, History, and the date picker): a glass tile whose fill fades from its top to clear
     by its middle (the stars show through it; its words and sprites don't), and its edge. A day below $0 is red. A zoomed
     day (budgetStyle.css) is solid (--DAY_SOLID). Today glows (--GLOW_FILL). */
  --DAY_FILL: linear-gradient(180deg, rgba(34, 36, 96, 0.62) 0%, rgba(34, 36, 96, 0) 50%);
  --DAY_SOLID: linear-gradient(180deg, rgb(30, 32, 86), rgb(10, 10, 32));
  --DAY_EDGE: rgba(120, 132, 255, 0.22);
  --DAY_RADIUS: clamp(4px, 0.9vmin, 10px);
  --NEGATIVE_DAY_FILL: linear-gradient(180deg, rgba(122, 14, 48, 0.68) 0%, rgba(122, 14, 48, 0) 50%);
  --NEGATIVE_DAY_SOLID: linear-gradient(180deg, rgb(112, 12, 44), rgb(42, 6, 24));
  --NEGATIVE_DAY_EDGE: rgba(255, 80, 100, 0.6);
  --NEGATIVE_GLOW_FILL: radial-gradient(ellipse at center, rgba(255, 70, 90, 0.5) 0%, rgba(200, 20, 50, 0.28) 50%, rgba(90, 0, 30, 0.1) 85%, transparent 100%);

  /* What a theme (themes.css) changes besides the colors above. The font. Then colors given as "red, green, blue", used
     as rgba(var(--GLOW_RGB), 0.5): the blue-violet glows and soft edges are made of (and a lighter one, for small glows
     and scroll bars), the red of a chosen control's glow, the dark shadows and dimmed pages are made of, the dark halo
     that keeps words readable over a busy spot, the navy of boxes to type in, the dark of other wells (hints, previews,
     a search's results), the white of faint tints, and the yellow of placeholders and connected spreadsheets. Then the
     orange edge of a picked day, a list that drops down, the words under the pointer or being typed, a recommended
     button's words, the line hr draws, a progress bar, and a page's icon tile. */
  --FONT: 'Main Font', sans-serif;
  --GLOW_RGB: 96, 112, 255;
  --GLOW_LIGHT_RGB: 150, 165, 255;
  --PICK_RGB: 200, 0, 0;
  --SHADE_RGB: 0, 0, 0;
  --HALO_RGB: 0, 0, 0;
  --WELL_RGB: 8, 10, 32;
  --INSET_RGB: 0, 0, 0;
  --TINT_RGB: 255, 255, 255;
  --YELLOW_RGB: 255, 205, 40;
  --BOX_FILL: rgba(var(--WELL_RGB), 0.6);
  --PICK_EDGE: #ff4500;
  --LIST_FILL: rgb(20, 17, 62);
  --TEXT_HOT: #fff;
  --PRIMARY_TEXT: var(--TEXT_BRIGHT);
  --LINE_GRADIENT: linear-gradient(90deg, transparent, rgba(110, 125, 255, 0.65) 25%, rgba(170, 95, 255, 0.65) 75%, transparent);
  --BAR_FILL: linear-gradient(90deg, #6a5cff, #c14dff);
  --TILE_FILL: radial-gradient(circle at 50% 40%, rgba(70, 90, 230, 0.35), rgba(12, 14, 44, 0.92));
}

/* #endregion 1) DESIGN TOKENS (ROOT VARIABLES) */



/* #region 2) DOCUMENT BASE + BACKGROUND */
/*========================================*
 *  2) DOCUMENT BASE + BACKGROUND
 *========================================*
 *  Which element scrolls changes: Boot.js holds the page still until it has slid in, then Layout.js
 *  gives scrolling back to the document. Changing overflow or height here can break the page
 *  transitions, and scrolling on iPhones.
 *
 *  No default margins or padding, a black background behind everything, and the base font and color.
 */

/*---------- Root document ----------*/
/* The site's font, Bpmf Huninn (SIL Open Font License), in two parts so a page only downloads what it
   shows: its Latin letters, numbers, Greek, and symbols (24 KB, every page; the pages preload it), and
   its Chinese, Japanese, and Bopomofo characters (1.8 MB, only when a page has one, like an entry titled
   in Chinese). Both come from BpmfHuninn-Regular.ttf, which no page loads anymore. */
@font-face {
  font-family: "Main Font";
  src: url("/Fonts/MainFont-Latin.woff2?v=854a3379ad") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-02FF, U+0370-03FF, U+2000-27BF;
}

@font-face {
  font-family: "Main Font";
  src: url("/Fonts/MainFont-More.woff2?v=78a7b4bd30") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+3000-31FF, U+3300-33FF, U+4E00-9FFF, U+F000-F5FF, U+FE30-FE52, U+FF00-FFEF, U+2546E, U+2AE5A;
}

html {
  margin: 0;
  padding: 0;
  inset: 0;

  width: 100vw;
  overflow-x: hidden;
  overflow-y: auto;

  /* The color at the edges while a page slides */
  background-color: black;
}

/*---------- Body (content wrapper) ----------*/
body {
  /* A column, so the footer stays under the page */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  min-height: 100vh;

  /* The body doesn't scroll by itself (Boot.js and Layout.js decide who does) */
  height: auto;
  width: 100vw;
  overflow-x: hidden;
  overflow-y: visible;

  margin: 0;
  padding: 0;
  inset: 0;

  /* See-through, so the starfield and background show */
  background: transparent;

  /* Base typography */
  text-align: center;
  font-family: var(--FONT); /* Letters the font doesn't have (like ñ) use a plain sans-serif */
  font-size: 7vmin;
  color: var(--BASE_COLOR);
  user-select: none;
  -webkit-user-select: none;
}

/* Main content wrapper (JS toggles who scrolls) */
#transitionContainer {
  flex: 1;
  min-height: 96vh;
  height: auto;
  width: 96vw;
  padding:2vh 2vw;
  inset: 0;

  /* Boot.js and Layout.js switch which element scrolls, so keep these as they are */
  overflow-x: hidden;
  overflow-y: hidden;
}

/* #endregion 2) DOCUMENT BASE + BACKGROUND */



/* #region 3) CANVAS LAYER */
/*========================================*
 *  3) CANVAS LAYER
 *========================================*
 *  The canvas is both the starfield's drawing surface and the background image. It's fixed to the
 *  screen at full size behind everything, and taps go through it.
 */

/* Full-screen starfield canvas (above bg, below content). Its background picture is Resources/Background.webp
   inside this stylesheet (_tools/stamp.mjs keeps the copy matching the file), so it paints with a page's very
   first frame instead of a moment after it; the color under it is the picture's own average. */
#constellations {
  position: fixed;
  inset: 0;

  width: 100lvw;
  height: 100lvh;

  background-color: rgb(5, 4, 29);
  background-image: url("data:image/webp;base64,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") /* inline: /Resources/Background.webp */;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;

  z-index: -1;

  pointer-events: none;
}

/* #endregion 3) CANVAS LAYER */



/* #region 4) PAGE STRUCTURE + TYPOGRAPHY */
/*========================================*
 *  4) PAGE STRUCTURE + TYPOGRAPHY
 *========================================*
 *  Text sizes and spacing. The footer's text is smaller, and dividers (hr, and the narrower .divider)
 *  are an image instead of a line.
 */

h3 {
  font-size: 12vmin;
}

h4 {
  font-size: 7vmin;
}

p {
  margin: 0;
  font-size: 6vmin;
}


footer p, footer a{
  font-size: clamp(12px, 2.4vmin, 16px);
  padding: 2vmin;
  color: var(--TEXT_DIM);
}

/* Dividers: a thin neon line that fades out at both ends */
hr {
  width: min(75vw, 900px);
  height: 1px;
  border: none;
  background: var(--LINE_GRADIENT);
  box-shadow: 0 0 8px rgba(var(--GLOW_RGB), 0.45);
}

/* Smaller divider variant */
.divider {
  width: 45vw;
}

/* #endregion 4) PAGE STRUCTURE + TYPOGRAPHY */



/* #region 5) CONTENT CONTAINERS */
/*========================================*
 *  5) CONTENT CONTAINERS
 *========================================*
 *  An article stacks its content in a column, as wide as its content, centered on the page.
 */

article {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: fit-content;
  margin: 0 auto 3vmin;
}

/* Anything with [hidden] stays hidden, even elements given a display (like inputs) */
[hidden] {
  display: none !important;
}

/* #endregion 5) CONTENT CONTAINERS */



/* #region 6) LINKS */
/*========================================*
 *  6) LINKS
 *========================================*
 *  Links are the neutral color, and grow a little, glow, and turn red on hover.
 */

a {
  /* A box of its own, so growing on hover doesn't move anything around it */
  display: inline-block;
  margin: 0 auto;
  padding-bottom: 1vmin;
  color: var(--BASE_COLOR);
  transition:
    transform var(--SLOW_TRANSFORM),
    color var(--SLOW_COLOR),
    text-shadow var(--SLOW_SHADOW);
}

a:hover {
  transform: scale(1.05);
  text-shadow: var(--SHADOW);
  color: var(--LINK_LIGHT);
}

/* #endregion 6) LINKS */



/* #region 7) IMAGES */
/*========================================*
 *  7) IMAGES
 *========================================*
 *  Images are round by default (the logo and Bob's picture start from this). Icons (.navIcon, .tabIcon, a
 *  card's icon) and the sprites (img.sprite, near the end) have their own rules.
 */

img {
  width: 40vmin;
  height: 40vmin;
  border-radius: 50%;
  object-fit: cover;
  overflow: hidden;
}

/* #endregion 7) IMAGES */



/* #region 8) BUTTONS */
/*========================================*
 *  8) BUTTONS
 *========================================*
 *  Pill-shaped glass buttons, the same everywhere (Home's are the model):
 *   - one that can be tapped is bright glass with a light edge; under the pointer it grows a little, and its edge
 *     brightens and glows blue-violet;
 *   - the recommended one (Save, Add Entry, Sign In: .primary) glows like Quick Entry;
 *   - one that's not recommended (Delete, Delete Account: .danger), and one that can't be used now (disabled), is darker;
 *   - a chosen one (a picked refraction type or account, Cost or Gain, an open date picker's button) has the red-orange
 *     gradient border and a red glow (GRADIENT BORDERS).
 */

button {

  -webkit-appearance: none;
  appearance: none;

  display: block;
  margin: 3vmin auto 1vmin;
  padding: 0.5em 1.5em;
  height: auto;

  object-fit: contain;

  border: 1.5px solid var(--GLASS_LINE_BRIGHT);
  border-radius: 9999px;
  background: var(--GLASS_BUTTON);
  box-shadow: inset 0 1px 0 rgba(var(--TINT_RGB), 0.06);

  color: var(--TEXT_BRIGHT);
  font-family: var(--FONT);
  font-size: 5vmin;

  transition:
    transform var(--SLOW_TRANSFORM),
    box-shadow var(--SLOW_SHADOW),
    border-color var(--SLOW_BORDER),
    color var(--SLOW_COLOR);
}

button:hover {
  /* It grows, and its edge brightens and glows */
  transform: scale(1.05);
  color: var(--TEXT_HOT);
  border-color: var(--GLOW_EDGE);
  box-shadow: var(--HOVER_SHADOW);
}

/* Can't be used now: darker, and it doesn't react */
button:disabled {
  opacity: 0.45;
  background: var(--DARK_BUTTON);
  pointer-events: none;
}

/* A button's small picture before its words (Undo, Redo, Search, Quick Entry): an image from Resources/Icons, as a
   background, so a button made by a script can have one too */
.buttonIcon {
  display: inline-block;
  flex-shrink: 0;
  width: 1.15em;
  height: 1.15em;
  background: center / contain no-repeat;
}

.iconUndo   { background-image: url("/Resources/Icons/Undo.webp?v=e50d463c17"); }
.iconRedo   { background-image: url("/Resources/Icons/Redo.webp?v=7f58fc6f43"); }
.iconSearch { background-image: url("/Resources/Icons/Search.webp?v=46152f5765"); }
.iconQuick  { background-image: url("/Resources/Icons/QuickEntry.webp?v=a219571ba6"); }

/* The calendar on a date box's button: thin light grey lines (--BASE_COLOR), like the site's other small marks (?, ×,
   and the date picker's ‹ and ›) */
.iconCalendar {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23c9cce4' stroke-width='1.3' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3.5' y='5' width='17' height='15.5' rx='2.5'/%3E%3Cpath d='M3.5 9.5h17M8 3v4M16 3v4M7.6 13.2h.8M11.6 13.2h.8M15.6 13.2h.8M7.6 16.6h.8M11.6 16.6h.8'/%3E%3C/svg%3E");
}

/* #endregion 8) BUTTONS */



/* #region 9) HEADER */
/*========================================*
 *  9) HEADER
 *========================================*
 *  Every page's header: the logo and the page's name (Home and its tabs: Prismal Planning, with its tagline) at the
 *  left, and its buttons at the right, each an icon over its name on a glass tile.
 */
header {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 1vmin 2vw;
  box-sizing: border-box;
}

/* The page's own header, as wide as its content */
#transitionContainer > header {
  gap: clamp(8px, 2vw, 24px);
  width: var(--PAGE_WIDTH);
  margin: 0 auto clamp(10px, 2.2vmin, 22px);
  padding: clamp(6px, 1.5vmin, 14px) 0 0;
}

/* Left side: the logo and the page's name */
header .brand {
  display: flex;
  align-items: center;
  gap: clamp(8px, 2vw, 18px);
  min-width: 0;
}

/* The logo never gets narrower than it is tall (the header's row would shrink its width on a skinny screen, but not
   its height) */
header .brand-icon {
  flex-shrink: 0;
  width: clamp(40px, 10vmin, 76px);
  height: clamp(40px, 10vmin, 76px);
  aspect-ratio: 1;
  border-radius: 50%;
  object-fit: cover;
  filter: drop-shadow(0 0 10px rgba(var(--GLOW_RGB), 0.45));
}

.brandText {
  display: flex;
  flex-direction: column;
  min-width: 0;
  text-align: left;
}

/* The name: "Prismal" heavier than "Budget" */
header .logo {
  margin: 0;
  font-size: clamp(17px, 4.6vmin, 36px);
  font-weight: normal;
  line-height: 1.1;
  text-align: left;
  color: var(--TEXT_BRIGHT);
  text-shadow: var(--TITLE_GLOW);
}

.logoStrong {
  font-weight: bold;
}

.tagline {
  margin: 0.3em 0 0;
  font-size: clamp(10px, 2.3vmin, 16px);
  letter-spacing: 0.05em;
  white-space: nowrap;
  color: var(--TEXT_BRIGHT);
  opacity: 0.85;
}

/* A page's name over "Prismal Planning" (Settings, the menu's pages, and the rest) */
header .stacked {
  justify-content: center;
  gap: 0.3em;
}

header .stacked h1 {
  margin: 0;
  font-size: clamp(17px, 4.2vmin, 32px);
  font-weight: normal;
  text-align: left;
  line-height: 1.15;
  color: var(--TEXT_BRIGHT);
  text-shadow: var(--TITLE_GLOW);
}

header .stacked h2 {
  margin: 0;
  font-size: clamp(11px, 2.4vmin, 16px);
  text-align: left;
  font-weight: normal;
  color: var(--TEXT_DIM);
}

/* The narrowest phones have no room for the tagline beside the buttons, and a page's long name (like
   Spreadsheets & Calendars) is a little smaller there, so it fits */
@media (max-width: 339px) {
  .tagline {
    display: none;
  }

  header .stacked h1 {
    font-size: 15px;
  }
}

/* Right side: the page's buttons (Settings, Menu, Logout, Home, Back), each an icon over its name */
.navButtons {
  display: flex;
  flex-direction: row;
  flex-shrink: 0;
  align-items: center;
  gap: clamp(5px, 1.4vw, 14px);
  margin: 0; /* No auto margins, so it stays right-aligned */
}

.navButtons a.navButton {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4em;
  box-sizing: border-box;
  width: clamp(48px, 14.5vw, 96px);
  height: clamp(54px, 14.5vw, 84px);
  margin: 0;
  padding: 0.3em 0.2em;
  font-size: clamp(10px, 2.7vw, 14px);
  line-height: 1;
  color: var(--TEXT_BRIGHT);
  text-decoration: none;
  background: var(--GLASS);
  border: 1px solid var(--GLASS_LINE);
  border-radius: 14px;
  box-shadow: var(--GLASS_SHADOW);
  transition: transform var(--SLOW_TRANSFORM), box-shadow var(--SLOW_SHADOW), border-color var(--SLOW_BORDER);
}

.navButtons a.navButton:hover,
.navButtons a.navButton:focus-visible {
  transform: scale(1.05);
  color: var(--TEXT_HOT);
  text-shadow: none;
  outline: none;
  border-color: var(--GLOW_EDGE);
  box-shadow: var(--HOVER_SHADOW);
}

.navIcon {
  width: clamp(22px, 6vw, 36px);
  height: clamp(22px, 6vw, 36px);
  border-radius: 0;
  object-fit: contain;
}

/* Signed in, the budget picker sits above the buttons (Budgets.js), exactly as wide as they are together (its width of 0
   and min-width of 100% keep a long name from widening it): the budget that's open, cut short with "..." when it's long,
   a ▾, and a pink dot while invitations wait */
.headerSide {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  flex-shrink: 0;
  gap: clamp(4px, 1vmin, 8px);
}

.headerSide button.budgetPicker {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.45em;
  box-sizing: border-box;
  width: 0;
  min-width: 100%;
  margin: 0;
  padding: 0.4em 0.9em;
  font-size: clamp(11px, 2.8vw, 14px);
  line-height: 1.2;
  background: var(--GLASS);
  border: 1px solid var(--GLASS_LINE);
  box-shadow: var(--GLASS_SHADOW);
}

.headerSide button.budgetPicker:hover,
.headerSide button.budgetPicker:focus-visible,
.headerSide button.budgetPicker[aria-expanded="true"] {
  transform: none;
  outline: none;
  color: var(--TEXT_HOT);
  border-color: var(--GLOW_EDGE);
  box-shadow: var(--HOVER_SHADOW);
}

.budgetPickerName {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.budgetPickerArrow {
  flex-shrink: 0;
  font-size: 0.85em;
  opacity: 0.8;
}

.budgetPickerDot {
  flex-shrink: 0;
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background: var(--NEON_PINK);
  box-shadow: 0 0 8px var(--NEON_PINK);
}

.budgetPickerDot[hidden] {
  display: none;
}

/* Each icon glows in its own color (the colored ones are dark on their own, so they're lifted a little). Home's is green
   like Menu's, and Back's red (HomeNav and BackNav: the tabs' Home and the Undo buttons keep their own icons). */
.navIcon[src*="/Settings."] { filter: brightness(1.35) drop-shadow(0 0 6px rgba(40, 100, 255, 0.85)); }
.navIcon[src*="/Menu."],
.navIcon[src*="/HomeNav."]  { filter: drop-shadow(0 0 6px rgba(40, 220, 40, 0.6)); }
.navIcon[src*="/BackNav."]  { filter: drop-shadow(0 0 6px rgba(255, 50, 40, 0.65)); }
.navIcon[src*="/Logout."]   { filter: brightness(1.2) drop-shadow(0 0 6px rgba(230, 0, 200, 0.7)); }

/* Logout's name is pink, like its icon */
.logoutButton span {
  color: #ec7dff;
}

/* #endregion 9) HEADER */

/* #region 10) SLIDE-IN PAGE TRANSITION SYSTEM */
/*========================================*
 *  10) SLIDE-IN PAGE TRANSITION SYSTEM
 *========================================*
 *  #transitionContainer holds the whole page. Layout.js gives it .ready once it has slid in (its
 *  resting place) and .slide-out when a link is followed. Boot.js gives html .homeJs on Home and
 *  .otherJs everywhere else. .noJs (JavaScript is off) hides the page and asks for JavaScript instead.
 *  A page slides out one way, and the next one slides in the same way (Layout.js slideWay picks it):
 *  left (.toLeft, then html.fromRight), right (.toRight, then html.fromLeft), down (into Settings,
 *  then html.fromTop), or up (.toTop, out of Settings). Anything else slides down and out, and the next
 *  page up into view.
 *  Between the budget's four pages (their tabs), the header and the tabs stay put and only the rest
 *  of the page slides: Layout.js gives the container .tab-slide-out when a tab is followed, and Boot.js
 *  gives the next page html.tabSlide until it has slid in.
 */

/* Where a page waits to slide in: below the screen, or the side it comes from */
.homeJs #transitionContainer,
.otherJs #transitionContainer {
  transform: translateY(100vh);
  transition: transform var(--SLIDE_DURATION) ease-in-out;
}

html.fromRight #transitionContainer {
  transform: translateX(110vw);
}

html.fromLeft #transitionContainer {
  transform: translateX(-110vw);
}

/* From above, only its first screen shows while it slides (the rest of a long page would run past ahead of it) */
html.fromTop #transitionContainer {
  transform: translateY(-110vh);
  clip-path: inset(0 0 max(0px, calc(100% - 100vh)) 0);
}

.homeJs #transitionContainer.ready,
.otherJs #transitionContainer.ready {
  transform: translateY(0);
}

/* Leaving: down and out, unless it says which way. Layout.js sets how far (just past the screen's edge), and when it
   slides up or down, clips it to the part on the screen first. */
.homeJs #transitionContainer.slide-out,
.otherJs #transitionContainer.slide-out {
  transition: transform var(--SLIDE_DURATION) ease-in-out;
  transform: translateY(var(--SLIDE_DISTANCE));
}

.homeJs #transitionContainer.slide-out.toTop,
.otherJs #transitionContainer.slide-out.toTop {
  transform: translateY(calc(-1 * var(--SLIDE_DISTANCE)));
}

.homeJs #transitionContainer.slide-out.toLeft,
.otherJs #transitionContainer.slide-out.toLeft {
  transform: translateX(calc(-1 * var(--SLIDE_DISTANCE)));
}

.homeJs #transitionContainer.slide-out.toRight,
.otherJs #transitionContainer.slide-out.toRight {
  transform: translateX(var(--SLIDE_DISTANCE));
}

/* A tab followed: everything but the header and the tabs slides down and out */
#transitionContainer.tab-slide-out > main > :not(.pageTop),
#transitionContainer.tab-slide-out .pageTop > :not(.pageTabs),
#transitionContainer.tab-slide-out > footer {
  transform: translateY(var(--SLIDE_DISTANCE));
  transition: transform var(--SLIDE_DURATION) ease-in-out;
}

/* ...and on the next page, the header and the tabs are already in place while the rest slides up into view (at
   rest, the parts have no transform at all: one would keep a zoomed day under the dimmed page) */
html.tabSlide #transitionContainer,
html.tabSlide #transitionContainer.ready {
  transform: none;
  transition: none;
}

html.tabSlide #transitionContainer > main > :not(.pageTop),
html.tabSlide #transitionContainer .pageTop > :not(.pageTabs),
html.tabSlide #transitionContainer > footer {
  transition: transform var(--SLIDE_DURATION) ease-in-out;
}

html.tabSlide #transitionContainer:not(.ready) > main > :not(.pageTop),
html.tabSlide #transitionContainer:not(.ready) .pageTop > :not(.pageTabs),
html.tabSlide #transitionContainer:not(.ready) > footer {
  transform: translateY(100vh);
}

/* No javascript fallback: nothing works without it, so the page only asks for it (the front page, which is
   just reading, shows as it is). The same goes for a browser that blocks site data (Boot.js adds
   .noStorage): signing in needs it. */
.noJs:not(.frontPage) #transitionContainer,
.noStorage #transitionContainer {
  display: none;
}

.noJs:not(.frontPage) body::before {
  content: "Prismal Planning needs JavaScript to work. Please turn on JavaScript in your browser's settings, then reload this page.";
}

.noStorage body::before {
  content: "Prismal Planning needs to keep a little data in your browser (that's how it keeps you signed in), and this browser is blocking it. Allow cookies and site data for this site in your browser's settings, then reload this page.";
}

.noJs body::before,
.noStorage body::before {
  margin: auto;
  padding: 6vmin;
  max-width: 80vw;
  font-size: clamp(18px, 5vmin, 40px);
  line-height: 1.4;
  text-shadow: 0 0 10px rgb(0, 0, 0);
}

/* #endregion 10) SLIDE-IN PAGE TRANSITION SYSTEM */



/* #region 11) REDUCED-MOTION ACCESSIBILITY */
/*========================================*
 *  11) REDUCED-MOTION ACCESSIBILITY
 *========================================*
 *  When users request reduced motion:
 *   1) remove the animated canvas layer
 *   2) disable page slide transitions
 */

@media (prefers-reduced-motion: reduce) {
  #constellations {
    display: none; /* disable animated starfield */
  }

  /* As specific as the slide rules above (and after them), so these win: the page just appears.
     Layout.js turns scrolling back on without waiting for a slide to end. */
  .homeJs #transitionContainer,
  .otherJs #transitionContainer,
  html.fromRight #transitionContainer,
  html.fromLeft #transitionContainer,
  html.fromTop #transitionContainer,
  .homeJs #transitionContainer.ready,
  .otherJs #transitionContainer.ready,
  .homeJs #transitionContainer.slide-out,
  .otherJs #transitionContainer.slide-out,
  .homeJs #transitionContainer.slide-out.toTop,
  .otherJs #transitionContainer.slide-out.toTop,
  .homeJs #transitionContainer.slide-out.toLeft,
  .otherJs #transitionContainer.slide-out.toLeft,
  .homeJs #transitionContainer.slide-out.toRight,
  .otherJs #transitionContainer.slide-out.toRight,
  #transitionContainer.tab-slide-out > main > :not(.pageTop),
  #transitionContainer.tab-slide-out .pageTop > :not(.pageTabs),
  #transitionContainer.tab-slide-out > footer,
  html.tabSlide #transitionContainer > main > :not(.pageTop),
  html.tabSlide #transitionContainer .pageTop > :not(.pageTabs),
  html.tabSlide #transitionContainer > footer,
  html.tabSlide #transitionContainer:not(.ready) > main > :not(.pageTop),
  html.tabSlide #transitionContainer:not(.ready) .pageTop > :not(.pageTabs),
  html.tabSlide #transitionContainer:not(.ready) > footer {
    transform: none;
    transition: none;
  }

  html.fromTop #transitionContainer {
    clip-path: none;
  }
}

/* Settings' Reduced Motion, on this device (Boot.js gives html .lessMotion when its animations switch is on, or the
   device asks for less motion): the same, with the starfield left as it is (its own switch holds it still instead,
   Active Starfield.js) */
html.lessMotion.homeJs #transitionContainer,
html.lessMotion.otherJs #transitionContainer,
html.lessMotion.fromRight #transitionContainer,
html.lessMotion.fromLeft #transitionContainer,
html.lessMotion.fromTop #transitionContainer,
html.lessMotion.homeJs #transitionContainer.ready,
html.lessMotion.otherJs #transitionContainer.ready,
html.lessMotion.homeJs #transitionContainer.slide-out,
html.lessMotion.otherJs #transitionContainer.slide-out,
html.lessMotion.homeJs #transitionContainer.slide-out.toTop,
html.lessMotion.otherJs #transitionContainer.slide-out.toTop,
html.lessMotion.homeJs #transitionContainer.slide-out.toLeft,
html.lessMotion.otherJs #transitionContainer.slide-out.toLeft,
html.lessMotion.homeJs #transitionContainer.slide-out.toRight,
html.lessMotion.otherJs #transitionContainer.slide-out.toRight,
html.lessMotion #transitionContainer.tab-slide-out > main > :not(.pageTop),
html.lessMotion #transitionContainer.tab-slide-out .pageTop > :not(.pageTabs),
html.lessMotion #transitionContainer.tab-slide-out > footer,
html.lessMotion.tabSlide #transitionContainer > main > :not(.pageTop),
html.lessMotion.tabSlide #transitionContainer .pageTop > :not(.pageTabs),
html.lessMotion.tabSlide #transitionContainer > footer,
html.lessMotion.tabSlide #transitionContainer:not(.ready) > main > :not(.pageTop),
html.lessMotion.tabSlide #transitionContainer:not(.ready) .pageTop > :not(.pageTabs),
html.lessMotion.tabSlide #transitionContainer:not(.ready) > footer {
  transform: none;
  transition: none;
}

html.lessMotion.fromTop #transitionContainer {
  clip-path: none;
}

/* #endregion 11) REDUCED-MOTION ACCESSIBILITY */

/* An image that couldn't load (Layout.js) shows its words instead, in the same spot and size */
.missingImage {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  text-align: center;
  font-size: max(12px, 2.4vmin);
  line-height: 1.1;
  overflow: hidden;
  overflow-wrap: anywhere;
}

/* The entry types' and In Bank, Gains, and Costs images (Sprites.js): sized like the letters around them, wherever
   they are. Not the round pictures every other img is (section 7). */
img.sprite {
  display: inline-block;
  width: 1.15em;
  height: 1.15em;
  margin: 0 0.05em;
  padding: 0;
  border: none;
  border-radius: 0;
  object-fit: contain;
  vertical-align: -0.22em;
  box-shadow: none;
  transform: none;
}

/* One that couldn't load is just its emoji again, in line with the text */
.sprite.missingImage {
  display: inline;
  font-size: inherit;
  line-height: inherit;
  overflow: visible;
}

/* The screen layer (Layout.js): floating windows, opened over the part of the page that's on the screen, at their normal
   size, even while the page is pinch-zoomed or a phone's keyboard is up (Layout.js sizes and places it from the browser's
   visual viewport). While a window is open, the layer is pinned to the page where it opened (.isPinned), so the page
   scrolls and zooms with it. The note layer (notes, the idle sign-out's countdown, and the version badge) always follows
   the screen, over the windows. Taps go through both, except on what's in them. Fixed boxes in them are placed in them,
   not on the page. */
#screenLayer,
#noteLayer {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1000;
  width: 100%;
  height: 100%;
  transform-origin: 0 0;
  pointer-events: none;
}

#screenLayer.isPinned {
  position: absolute;
}

#noteLayer {
  z-index: 1600;
}

#screenLayer > *,
#noteLayer > .idleWarning {
  pointer-events: auto;
}

/* The release's name, small, in the screen's bottom left corner */
#versionBadge {
  position: absolute;
  bottom: 4px;
  left: 6px;
  font: 10px monospace;
  opacity: .45;
  z-index: 9999;
}

/*========================================*
 *  12) FORM ELEMENTS (LOGIN/REGISTER)
 *========================================*/
form {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
}

label {
  font-size: 5vmin;
  color: var(--BASE_COLOR);
  margin-top: 2vmin;
}

input {
  -webkit-appearance: none;
  appearance: none;

  display: block;
  margin: 1vmin auto 3vmin;
  padding: 0.5em 1em;
  width: 60vw;
  max-width: 400px;

  /* A glass pill, like the buttons */
  background: var(--BOX_FILL);
  border: 1.5px solid var(--GLASS_LINE_BRIGHT);
  border-radius: 9999px;

  /* Match typography. A steady size (one that grows with the screen gets huge on wide ones); 16px at
     least, so phones don't zoom in when a box is tapped. */
  color: var(--TEXT_BRIGHT);
  font-family: var(--FONT);
  font-size: clamp(16px, 3.4vmin, 21px);
  text-align: center;

  transition:
    transform 0.3s ease-out,
    box-shadow var(--SLOW_SHADOW),
    border-color var(--SLOW_BORDER),
    color var(--SLOW_COLOR),
    text-shadow var(--SLOW_SHADOW);
}

/* A password's hidden characters: the plain font's dots, small and evenly spaced (the site's font draws
   them big) */
input[type="password"] {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  letter-spacing: 0.12em;
}

/* Where the Tab key is, in the theme's own color (what styles its own focus goes by that), and the link past the header that's
   only there for the Tab key */
:focus-visible {
  outline: 2px solid var(--GLOW_EDGE);
  outline-offset: 2px;
}

.cell-content:focus-visible {
  outline-offset: -2px;
}

.skipLink {
  position: fixed;
  top: -5em;
  left: 0.6em;
  z-index: 10000;
  padding: 0.5em 1em;
  color: var(--TEXT_BRIGHT);
  background: var(--LIST_FILL);
  border: 1px solid var(--GLASS_LINE_BRIGHT);
  border-radius: 8px;
}

.skipLink:focus {
  top: 0.6em;
}

/* The box being typed in has a bright edge (GRADIENT BORDERS' boxes, at the end), and nothing else moves or glows */
input:focus {
  outline: none;
  color: var(--TEXT_HOT);
}
.hidden {
  display: none !important;
}

/* The last minute before an idle sign-out (Session.js). Here, not in budgetStyle.css: every signed-in
   page shows it, and the 404 page doesn't load budgetStyle.css. */
.idleWarning {
  position: fixed;
  top: max(2vh, env(safe-area-inset-top, 0px));
  left: 50%;
  z-index: 2100;
  transform: translateX(-50%);
  box-sizing: border-box;
  width: max-content;
  max-width: min(92vw, 560px);
  padding: 0.7em 1.2em;
  font-size: clamp(13px, 2.6vmin, 18px);
  line-height: 1.4;
  text-align: center;
  color: var(--BASE_COLOR);
  background: var(--HOVER_GRADIENT);
  border: 2px solid transparent; /* The gradient border: GRADIENT BORDERS */
  border-radius: 14px;
  box-shadow: 0 10px 25px rgba(var(--SHADE_RGB), 0.6), 0 0 14px rgba(var(--PICK_RGB), 0.35);
}

/* Checkboxes (the input style above hides native controls). A set size: em would follow the input
   style's 5vmin text, which made them huge on big screens. */
input[type="checkbox"] {
  -webkit-appearance: checkbox;
  appearance: auto;
  display: inline-block;
  flex-shrink: 0;
  width: clamp(16px, 2.2vmin, 20px);
  height: clamp(16px, 2.2vmin, 20px);
  margin: 0;
  padding: 0;
  border: none;
  font-size: inherit;
  accent-color: var(--LINK_LIGHT);
  cursor: pointer;
}

input[type="checkbox"]:hover,
input[type="checkbox"]:focus {
  transform: none;
  box-shadow: none;
}

/* Pill switches: an on/off choice, like "Turn on passkey sign-in" (checkboxes that pick rows from a list, like
   search results, stay checkboxes). Still a checkbox underneath (with role="switch"), so forms and screen
   readers work the same. Off: a dark pill with a gray knob at the left. On: the red-orange gradient, with a
   white knob at the right. The knob is a background layer, so it works on every browser. */
input[type="checkbox"].pillSwitch {
  --SWITCH_H: clamp(24px, 3vmin, 30px);
  --KNOB: calc(var(--SWITCH_H) - 8px);
  box-sizing: border-box;
  width: calc(var(--SWITCH_H) * 1.8);
  height: var(--SWITCH_H);
  -webkit-appearance: none;
  appearance: none;
  border: 2px solid var(--GLASS_LINE_BRIGHT);
  border-radius: 9999px;
  background:
    radial-gradient(circle closest-side, var(--BASE_COLOR) 90%, transparent 100%) left 2px center / var(--KNOB) var(--KNOB) no-repeat,
    var(--BOX_FILL);
  transition: background-position 0.2s ease, border-color 0.2s ease, box-shadow var(--SLOW_SHADOW);
}

input[type="checkbox"].pillSwitch:checked {
  border-color: transparent;
  background:
    radial-gradient(circle closest-side, #fff 90%, transparent 100%) right 2px center / var(--KNOB) var(--KNOB) no-repeat,
    var(--EDGE_GRADIENT) border-box;
}

input[type="checkbox"].pillSwitch:hover,
input[type="checkbox"].pillSwitch:focus-visible {
  box-shadow: var(--SHADOW);
}

input[type="checkbox"].pillSwitch:disabled {
  opacity: 0.5;
  cursor: default;
}

@media (prefers-reduced-motion: reduce) {
  input[type="checkbox"].pillSwitch {
    transition: none;
  }
}

html.lessMotion input[type="checkbox"].pillSwitch {
  transition: none;
}

/* Create account: agree to the Privacy Policy & Terms of Use */
.termsField {
  display: flex;
  align-items: center;
  gap: 2vmin;
  max-width: 80vw;
  margin: 1vmin auto 2vmin;
  font-size: 4vmin;
  text-align: left;
}

.termsField a {
  padding-bottom: 0;
}

/* Create Account's check that this is a person (Cloudflare Turnstile): empty unless it needs a tap, then its box,
   centered and no wider than the form */
.turnstileField {
  display: flex;
  justify-content: center;
  max-width: min(92vw, 400px); /* Its box is at least 300px wide */
  margin: 0 auto;
}

.turnstileField:not(:empty) {
  margin: 1vmin auto 2vmin;
}

/* Login page instructions (forgot password, new password) */
.formHint {
  max-width: 80vw;
  margin: 2vmin auto;
  font-size: 4.5vmin;
}

/* A button that reads like a link (Forgot Password?) */
.textButton {
  margin-top: 2vmin;
  padding: 0.3em 0.8em;
  border: none;
  background: none;
  box-shadow: none;
  font-size: 4vmin;
}

.textButton:hover {
  box-shadow: none;
}

/* The login page's form, on a glass card: its boxes and buttons as wide as the card, with steady text sizes */
.authCard {
  box-sizing: border-box;
  width: min(92vw, 460px);
  margin: clamp(8px, 3vmin, 32px) auto 4vmin;
  padding: clamp(18px, 4vmin, 34px) clamp(16px, 4vmin, 34px);
  background: var(--GLASS);
  border: 1px solid var(--GLASS_LINE);
  border-radius: 20px;
  box-shadow: var(--GLASS_SHADOW), 0 0 30px rgba(var(--GLOW_RGB), 0.15);
}

.authCard form {
  align-items: stretch;
}

.authCard form > div {
  width: 100%;
}

.authCard label {
  display: block;
  margin: 0 0 0.35em;
  font-size: clamp(14px, 3.2vmin, 17px);
  text-align: left;
  color: var(--TEXT_DIM);
}

.authCard input:not([type="checkbox"]) {
  box-sizing: border-box;
  width: 100%;
  max-width: none;
  margin: 0 0 1.1em;
}

.authCard button {
  width: 100%;
  margin: 0.7em 0 0;
  font-size: clamp(15px, 3.4vmin, 19px);
}

/* Its main button (Sign In, Create Account, Send Reset Link...) is the recommended one: it glows like Quick Entry */
.authCard #primary-action-btn {
  color: var(--PRIMARY_TEXT);
  background: var(--GLOW_FILL), var(--RECOMMENDED_FILL);
  border-color: var(--GLOW_EDGE);
  box-shadow: var(--GLOW_SHADOW);
}

.authCard #primary-action-btn:hover {
  box-shadow: var(--GLOW_SHADOW), 0 0 22px rgba(var(--GLOW_RGB), 0.6);
}

.authCard .textButton {
  align-self: center;
  width: auto;
  margin: 0.9em auto 0;
  font-size: clamp(13px, 2.9vmin, 16px);
  color: var(--TEXT_DIM);
}

.authCard .textButton:hover {
  color: var(--TEXT_HOT);
}

/* On standby with signing in with Apple, Google, or Microsoft (Login.js): their buttons, under a line, plain white with
   dark words, the way each one's sign-in buttons look on a dark page

.authCard .providerButtons {
  display: flex;
  flex-direction: column;
  margin-top: 1em;
  padding-top: 0.4em;
  border-top: 1px solid var(--GLASS_LINE);
}

.authCard button.providerButton {
  color: #1f1f1f;
  background: #fff;
  border: 1px solid #dadce0;
  box-shadow: none;
  font-weight: 500;
}

.authCard button.providerButton:hover,
.authCard button.providerButton:focus-visible {
  background: #f2f2f2;
  box-shadow: 0 0 14px rgba(255, 255, 255, 0.25);
}
*/

.authCard .termsField,
.authCard .formHint {
  max-width: none;
  font-size: clamp(13px, 2.9vmin, 16px);
}

/* Its switches sit beside their words (the card's labels are otherwise a line of their own) */
.authCard .termsField {
  display: flex;
  margin: 0.2em 0 0.9em;
  color: var(--BASE_COLOR);
}

.authCard #status-message {
  margin: 0.4em 0 0;
  font-size: clamp(13px, 2.9vmin, 16px);
}

/*========================================*
 *  13) GRADIENT BORDERS
 *========================================*
 *  Chosen controls (a picked refraction type, account, or Cost or Gain; an open ? or date picker), the New Prism form,
 *  and the idle sign-out's countdown get a red-orange diagonal gradient border (--EDGE_GRADIENT), drawn as a ring over
 *  their own border (the ::before below), which keeps their round corners and see-through backgrounds. --EDGE_WIDTH is
 *  how thick it is, and --EDGE_OUTSET how far outside the padding it starts (their border's width, unless set). The
 *  buttons among them also get a red radial gradient from their center (--PICK_FILL) over their glass. Then the
 *  recommended and not recommended buttons (see BUTTONS), and text boxes: the one being typed in gets a bright edge,
 *  nothing more.
 */

button,
a.budgetButton {
  position: relative; /* The ring's frame */
  --EDGE_WIDTH: 2px;
}

.budgetPanel,
.idleWarning {
  --EDGE_WIDTH: 2px;
}

.fieldHelpButton {
  --EDGE_WIDTH: 1.5px;
}

/* The nav buttons' edge is 1px: the ring starts at its outside and runs 2px in */
.navButtons a {
  --EDGE_WIDTH: 2px;
  --EDGE_OUTSET: 1px;
}

.segmented .budgetButton[aria-checked="true"],
.choiceList .budgetButton[aria-checked="true"],
.fieldHelpButton[aria-expanded="true"],
button.pickDay[aria-expanded="true"],
.budgetPanel.prismDraft,
.calculatorForm.presetDraft,
.idleWarning {
  border-color: transparent;
}

/* The buttons among them also get the red radial gradient from their center */
.segmented .budgetButton[aria-checked="true"],
.choiceList .budgetButton[aria-checked="true"],
.fieldHelpButton[aria-expanded="true"],
button.pickDay[aria-expanded="true"] {
  background: var(--PICK_FILL), var(--GLASS_BUTTON);
}

.segmented .budgetButton[aria-checked="true"]::before,
.choiceList .budgetButton[aria-checked="true"]::before,
.fieldHelpButton[aria-expanded="true"]::before,
button.pickDay[aria-expanded="true"]::before,
.budgetPanel.prismDraft::before,
.calculatorForm.presetDraft::before,
.idleWarning::before {
  content: "";
  position: absolute;
  inset: calc(-1 * var(--EDGE_OUTSET, var(--EDGE_WIDTH, 2px)));
  padding: var(--EDGE_WIDTH, 2px);
  border-radius: inherit;
  background: var(--EDGE_GRADIENT);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  pointer-events: none;
}

/* Recommended (Save, Add Entry, Set It Up): it glows like Home's Quick Entry, and a little more under the pointer */
.budgetButton.primary {
  color: var(--PRIMARY_TEXT);
  background: var(--GLOW_FILL), var(--RECOMMENDED_FILL);
  border-color: var(--GLOW_EDGE);
  box-shadow: var(--GLOW_SHADOW);
}

.budgetButton.primary:not(:disabled):hover {
  box-shadow: var(--GLOW_SHADOW), 0 0 22px rgba(var(--GLOW_RGB), 0.6);
}

/* Not recommended (Delete, Sign Out Everywhere, Delete Account): darker, its words a muted red */
.budgetButton.danger {
  color: var(--DANGER_TEXT);
  background: var(--DARK_BUTTON);
  border-color: rgba(255, 107, 122, 0.3);
  box-shadow: none;
}

.budgetButton.danger:not(:disabled):hover {
  color: var(--NEGATIVE_TEXT, #ff6b7a);
  border-color: rgba(255, 107, 122, 0.6);
  box-shadow: none;
}

/* Boxes: a little brighter edge under the pointer, and a bright one while it's being typed in. No glow. (A date box a tap
   on a day will fill shows it on the calendar instead: its dashed outline, budgetStyle.css body.datePicking.) */
input:not([type="checkbox"]):not([type="range"]):not([type="number"]):hover,
select:hover,
textarea:hover {
  border-color: var(--GLASS_LINE_BRIGHT);
}

input:not([type="checkbox"]):not([type="range"]):not([type="number"]):focus,
select:focus,
textarea:focus {
  border-color: var(--GLOW_EDGE);
  box-shadow: none;
}

/*========================================*
 *  14) DATE BOXES AND THE CALENDAR THAT PICKS A DAY (Dates.js)
 *========================================*
 *  A date box is typed in, with a calendar button beside it. The button opens a small calendar like Home's: the month
 *  and the year (each a box to type in, with a list that drops down under it) between ‹ and ›, then square days, each
 *  with its number. Here, not in budgetStyle.css: the login page (the birth date) uses it too.
 */

.dateRow {
  display: flex;
  align-items: center;
  gap: 0.5em;
}

.dateRow input.dateInput {
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
}

/* The login page's: the row keeps the boxes' spacing (its em is the boxes' text size, like theirs) */
.authCard .dateRow {
  margin: 0 0 1.1em;
  font-size: clamp(16px, 3.4vmin, 21px);
}

.authCard .dateRow input.dateInput {
  margin: 0;
}

/* The calendar button: a small glass button with the calendar icon, as tall as its box */
button.pickDay {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  width: auto;
  margin: 0;
  padding: 0 0.85em;
  font-size: clamp(15px, 2.8vmin, 18px);
  line-height: 1;
}

.authCard button.pickDay {
  width: auto;
  margin: 0;
  font-size: clamp(15px, 2.8vmin, 18px);
}

button.pickDay .buttonIcon {
  width: 1.35em;
  height: 1.35em;
}

/* Open: it's chosen (the red-orange ring and fill: GRADIENT BORDERS), with a red glow */
button.pickDay[aria-expanded="true"] {
  box-shadow: var(--PICK_SHADOW);
}

.datePicker {
  position: absolute;
  z-index: 1350;
  box-sizing: border-box;
  width: min(calc(100% - 16px), 340px);
  padding: 0.7em 0.75em 0.75em;
  font-size: clamp(14px, 2.6vmin, 17px);
  line-height: 1.2;
  color: var(--BASE_COLOR);
  text-align: center;
  background: var(--HOVER_GRADIENT);
  border: 1px solid var(--GLASS_LINE_BRIGHT);
  border-radius: 16px;
  box-shadow: var(--FLOAT_SHADOW);
  user-select: none;
  -webkit-user-select: none;
}

/* The month between ‹ and ›, then the year */
.pickerHead {
  display: flex;
  align-items: center;
  gap: 0.4em;
  margin: 0 0 0.6em;
}

.pickerChoice {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
}

.pickerChoice:has(.pickerMonth) {
  flex-grow: 1.45;
}

.datePicker input.pickerInput {
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  margin: 0;
  padding: 0.4em 0.4em;
  font-size: max(16px, 1em); /* Phones don't zoom in on a box of 16px or more */
  line-height: 1.2;
  text-align: center;
  border-radius: 10px;
}

.datePicker input.pickerInput:hover,
.datePicker input.pickerInput:focus {
  transform: none;
  box-shadow: none;
}

.datePicker .pickerStep {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: 2em;
  height: 2em;
  margin: 0;
  padding: 0 0 0.1em;
  font-size: 1.15em;
  line-height: 1;
  border-radius: 50%;
}

/* A box's list, dropped down under it */
.pickerList {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 2;
  max-height: 12.5em;
  margin: 0;
  padding: 0.3em 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  list-style: none;
  background: var(--LIST_FILL);
  border: 1px solid var(--GLASS_LINE_BRIGHT);
  border-radius: 10px;
  box-shadow: 0 12px 26px rgba(var(--SHADE_RGB), 0.65);
}

.pickerOption {
  padding: 0.38em 0.5em;
  cursor: pointer;
}

.pickerOption:hover,
.pickerOption.isActive {
  color: var(--TEXT_HOT);
  background: var(--PICK_FILL), rgba(var(--PICK_RGB), 0.22);
}

/* The weekdays over the days, like Home's calendar */
.pickerWeekdays,
.pickerDays {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px;
}

.pickerWeekdays {
  margin: 0 0 4px;
  font-size: 0.68em;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--TEXT_DIM);
}

/* Each day a square glass tile with its number, big, like a day on Home's calendar */
.datePicker .pickerDay {
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  aspect-ratio: 1;
  min-width: 0;
  margin: 0;
  padding: 0;
  font-size: 1.15em;
  font-weight: bold;
  line-height: 1;
  color: var(--TEXT_BRIGHT);
  background: var(--DAY_FILL);
  border: none;
  border-radius: 8px;
  box-shadow: inset 0 0 0 1px var(--DAY_EDGE);
  transition: box-shadow var(--SLOW_BORDER), background-color var(--SLOW_BORDER);
}

.datePicker .pickerDay.isOtherMonth {
  opacity: 0.4;
  font-weight: normal;
}

.datePicker .pickerDay.isToday {
  background: var(--GLOW_FILL), var(--DAY_FILL);
  box-shadow: inset 0 0 0 1px var(--GLOW_EDGE), 0 0 10px rgba(var(--GLOW_RGB), 0.6);
}

.datePicker .pickerDay:hover,
.datePicker .pickerDay:focus-visible {
  transform: none;
  outline: none;
  text-shadow: none;
  box-shadow: inset 0 0 0 1px var(--GLOW_EDGE), 0 0 10px rgba(var(--GLOW_RGB), 0.55);
}

/* The picked day: red, like a chosen button */
.datePicker .pickerDay.isPicked {
  color: var(--TEXT_HOT);
  background: var(--PICK_FILL), rgba(var(--PICK_RGB), 0.25);
  box-shadow: inset 0 0 0 2px var(--PICK_EDGE), 0 0 10px rgba(var(--PICK_RGB), 0.6);
}

.datePicker .pickerDay:disabled {
  opacity: 0.18;
  cursor: default;
  box-shadow: inset 0 0 0 1px var(--DAY_EDGE);
}

.pickerFoot {
  display: flex;
  justify-content: flex-end;
  gap: 0.5em;
  margin: 0.65em 0 0;
}

.pickerFoot button {
  margin: 0;
  padding: 0.4em 1.1em;
  font-size: 0.95em;
}

.pickerFoot button:first-child:not(:last-child) {
  margin-right: auto;
}

/*========================================*
 *  15) FLOATING CARDS
 *========================================*
 *  The page's cards hover in place: each one on the screen (Layout.js gives it .isFloating while it is) drifts a few
 *  pixels around its spot in a slow loop, on its own timing (Layout.js sets how far it goes each way, --FLOAT_X and
 *  --FLOAT_Y; how long a loop takes, --FLOAT_TIME; and when it starts, --FLOAT_DELAY). The loop moves the translate
 *  property, so a card's own transform (growing under the pointer) still works with it. A card holds still while a day
 *  in it is zoomed or held bigger: moving, it would keep the day under the dimmed page and the cards after it. Nothing
 *  floats with Reduced Motion's animations switch on, or for a device that asks for less motion. On a computer
 *  (html.pixelFloat), Layout.js moves the cards along the same loop by whole pixels instead.
 */
@keyframes cardFloat {
  0%    { translate: 0 0; }
  12.5% { translate: calc(var(--FLOAT_X) * 0.71) calc(var(--FLOAT_Y) * -0.15); }
  25%   { translate: var(--FLOAT_X) calc(var(--FLOAT_Y) * -0.5); }
  37.5% { translate: calc(var(--FLOAT_X) * 0.71) calc(var(--FLOAT_Y) * -0.85); }
  50%   { translate: 0 calc(var(--FLOAT_Y) * -1); }
  62.5% { translate: calc(var(--FLOAT_X) * -0.71) calc(var(--FLOAT_Y) * -0.85); }
  75%   { translate: calc(var(--FLOAT_X) * -1) calc(var(--FLOAT_Y) * -0.5); }
  87.5% { translate: calc(var(--FLOAT_X) * -0.71) calc(var(--FLOAT_Y) * -0.15); }
  100%  { translate: 0 0; }
}

.isFloating {
  animation: cardFloat var(--FLOAT_TIME, 9s) linear var(--FLOAT_DELAY, 0s) infinite;
}

/* Computers (a mouse or trackpad): Layout.js moves each card along the same loop by whole pixels of the screen instead,
   since moving by part of a pixel smears its words and lines there */
html.pixelFloat .isFloating {
  animation: none;
}

/* (Process Budget.js gives html .dayZoomed while a day is zoomed; :has() also catches a day shrinking back, and one held
   bigger on a computer) */
html.dayZoomed .isFloating.calendarCard,
html.dayZoomed .isFloating.pageCard {
  animation: none;
}

.isFloating:has(td.is-editing, td.is-magnified) {
  animation: none;
}

html.lessMotion .isFloating {
  animation: none;
}

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