/* ==========================================================================
   Small Wallet CSS
   ========================================================================== */

/* ==========================================================================
   1. Color Palette
   ========================================================================== */

/* Display face: Playfair Display (self-hosted variable, Latin + Latin-Ext) */
@font-face { font-family: 'Playfair Display'; font-style: normal; font-weight: 400 900; font-display: swap; src: url("../fonts/PlayfairDisplay-latin-ext.319e6b2aad48.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; }
@font-face { font-family: 'Playfair Display'; font-style: normal; font-weight: 400 900; font-display: swap; src: url("../fonts/PlayfairDisplay-latin.ef05b30d6e5c.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; }

:root {
  /* ================= Ligne 1 — an 80s transit map ==================
     One palette, no picker. Four lines do all the signalling, the way a
     network map does it: a colour means a line, never decoration. Money
     that grows rides the green line, money that drains rides the red,
     caution is the platform yellow, and the blue is the trunk — links,
     buttons, everything the interface offers you. There is deliberately
     no orange: it is the one hue that cannot be told from the yellow at
     a glance, and a fifth voice would only make the four harder to read.

     Everything else is paper, ink and rule: plain white, so the four
     lines are printed on nothing at all and each one carries its full
     strength. Flat — a map has no shadows.

     Still the one rule that matters: no colour is hardcoded anywhere
     else in the app. Every value lives here, which is what lets a
     single line below repaint the whole interface. */

  /* ---- Paper & ink: the sheet the map is printed on ----
     White, and the greys off it neutral: a warm cream next to white reads
     as a stain rather than as paper, so the secondary surfaces and the
     rules are the same sheet a shade down. */
  --paper: #FFFFFF;
  --paper-2: #F2F2F0;
  --ink: #14161A;
  --ink-soft: #3E434D;
  --ink-faint: #6B7280;
  --rule: #BFBFBC;
  --rule-soft: #E0E0DC;

  /* Panels that sit on the page rather than being the page (form
     fields, the nav pill). The same white as the paper in daylight —
     their border is what sets them apart there — and kept a separate
     name so the night cut can lift them off the dark page. */
  --surface: #FFFFFF;

  /* ---- The four lines ---- */
  --color-blue: #0B3DA8;      /* trunk line: links, actions, the offer   */
  --color-green: #00782A;     /* the green line: money kept, under budget*/
  --color-red: #C8102E;       /* the red line: overspending, danger      */
  --color-yellow: #F5C400;    /* platform stripe: a fill, never a word   */
  --color-yellow-ink: #7A5B00;/* the same yellow, dark enough to read    */

  /* The accent is the blue line: it is what the interface offers you. */
  --accent: var(--color-blue);
  --accent-hover: #08307F;
  --accent-glow: color-mix(in srgb, var(--color-blue) 18%, transparent);

  /* A highlighter over a figure — the yellow doing what yellow does. */
  --highlight: color-mix(in srgb, var(--color-yellow) 42%, transparent);

  /* Text that sits ON a filled swatch. Each is the far end of its own
     colour: white on the deep blue and red, and on the yellow the ink
     itself — the only way a yellow lozenge is ever legible. */
  --on-accent: #FFFFFF;
  --on-error: #FFFFFF;
  --on-warning: #FFFFFF;
  --on-success: #FFFFFF;

  /* ---- What each line means ---- */
  --color-error: var(--color-red);
  --color-success: var(--color-green);
  --color-warning: var(--color-yellow-ink);
  --color-info: var(--color-blue);
  --color-primary: var(--color-blue);

  /* ---- Neutrals ---- */
  --color-text: var(--ink);
  --color-text-muted: var(--ink-soft);
  --color-text-light: var(--ink-faint);
  --color-text-inactive: #96968F;
  --color-border: var(--rule);
  --color-border-light: var(--rule-soft);
  --color-bg-light: var(--paper-2);
  --color-bg-highlight: #E7E7E3;

  /* Display font (the ledger "book" face) — the romance is in the type,
     set against signage colour. */
  --font-display: "Playfair Display", "Iowan Old Style", "Palatino Linotype", Georgia, "Times New Roman", serif;

  /* ---- Notices: a station board. A fat band of the line's own colour
     down the left, the faintest wash of it behind, and the text left in
     plain ink so it is never the colour that has to be read. ---- */
  --color-alert-success-bg: color-mix(in srgb, var(--color-green) 8%, var(--surface));
  --color-alert-success-border: var(--color-green);
  --color-alert-success-text: var(--ink);
  --color-alert-warning-bg: color-mix(in srgb, var(--color-yellow) 18%, var(--surface));
  --color-alert-warning-border: var(--color-yellow);
  --color-alert-warning-text: var(--ink);
  --color-alert-danger-bg: color-mix(in srgb, var(--color-red) 8%, var(--surface));
  --color-alert-danger-border: var(--color-red);
  --color-alert-danger-text: var(--ink);
  --color-alert-info-bg: color-mix(in srgb, var(--color-blue) 7%, var(--surface));
  --color-alert-info-border: var(--color-blue);
  --color-alert-info-text: var(--ink);
  --color-alert-secondary-bg: var(--paper-2);
  --color-alert-secondary-border: var(--rule);
  --color-alert-secondary-text: var(--ink-soft);
}

/* The same map at night. The lines keep their identity and are brightened
   just enough to hold on a dark platform; the yellow, already bright,
   barely moves. Nobody chooses this — the device asks and the page
   answers, on the first frame, with no script and no flash. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper: #0F1114;
    --paper-2: #191C21;
    --ink: #F2F0E8;
    --ink-soft: #C0C4CC;
    --ink-faint: #878D98;
    --rule: #3A3F47;
    --rule-soft: #2A2E34;
    --surface: #171A1F;

    --color-blue: #5B9BFF;
    --color-green: #4CD07A;
    --color-red: #FF5A5A;
    --color-yellow: #FFD400;
    --color-yellow-ink: #F0C400;

    --accent-hover: #8FBBFF;

    /* On a brightened line, the legible word is the dark one. */
    --on-accent: #0B1220;
    --on-error: #1A0505;
    --on-warning: #1A1400;
    --on-success: #05170B;

    --color-text-inactive: #6B7078;
    --color-bg-highlight: #22262C;
  }
}

/* ==========================================================================
   2. Reset & Base Styles
   ========================================================================== */

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  background: var(--paper);
}

body {
  margin: 0 auto;
  max-width: 600px;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  font-family: Georgia, "Times New Roman", serif;
  letter-spacing: 0.03em;
  line-height: 1.5;
  padding: 1.5em 2em;
  font-size: 16px;
  color: var(--color-text);
  background-color: var(--paper);
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='140'%20height='140'%3E%3Cfilter%20id='n'%3E%3CfeTurbulence%20type='fractalNoise'%20baseFrequency='0.8'%20numOctaves='2'%20stitchTiles='stitch'/%3E%3CfeColorMatrix%20type='saturate'%20values='0'/%3E%3C/filter%3E%3Crect%20width='140'%20height='140'%20filter='url(%23n)'%20opacity='0.05'/%3E%3C/svg%3E");
}

/* ==========================================================================
   3. Typography
   ========================================================================== */

h1, h2, h3, h4, h5, h6 {
  margin-bottom: 1rem;
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink);
  letter-spacing: 0.01em;
}

h1, h2 {
  font-variant: small-caps;
  letter-spacing: 0.05em;
}

h1 { font-size: 1.5rem; }
h2 { font-size: 1.75rem; }
h3 { font-size: 1.5rem; }
h4 { font-size: 1.25rem; }
h5 { font-size: 1.1rem; }
h6 { font-size: 1rem; }

p { margin-bottom: 1rem; }

ul, ol {
  margin-bottom: 1rem;
  padding-left: 1.5em;
}

a {
  color: var(--color-primary);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

small {
  font-size: 0.875rem;
}

/* ==========================================================================
   4. Layout
   ========================================================================== */

.container {
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
  padding: 0 1rem;
}

.row {
  display: flex;
  flex-wrap: wrap;
}

.col { flex: 1 0 0%; }
.col-4 { flex: 0 0 33.333333%; max-width: 33.333333%; }
.col-6 { flex: 0 0 50%; max-width: 50%; }
.col-8 { flex: 0 0 66.666667%; max-width: 66.666667%; }
.col-12 { flex: 0 0 100%; max-width: 100%; }

.hide-mobile { }

@media (max-width: 768px) {
  .hide-mobile { display: none; }
  .col-4, .col-6, .col-8 {
    flex: 0 0 100%;
    max-width: 100%;
  }
  .row {
    flex-direction: column;
  }
}

/* Budget Page Layout */

/* ==========================================================================
   5. Navigation (element styles only)
   ========================================================================== */

/* No rule under the nav: the page opens on bare paper, and the colour is
   left to the figures that mean something. These rules are scoped to the
   site nav by id — a `nav` element elsewhere on a page (the savings page's
   view tabs) is its own thing and must not inherit the header's layout. */
/* Exactly one ledger row tall (2em), so the page below it starts on a whole
   number. Left to itself the bar takes the height of the wordmark's line box —
   25.2px in Playfair — and every row under it inherits that fraction. The
   min-height only ever grows the bar, so a wrapped breadcrumb still fits. */
#main-nav {
  min-height: 2em;
  margin-bottom: 1em;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1em;
}

#main-nav .nav-left { display: inline-flex; align-items: baseline; gap: 1em; }

#main-nav a, #main-nav ul a {
  color: var(--color-text);
}

#main-nav ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 1em;
}

#main-nav li {
  display: inline;
}

#main-nav a {
  text-decoration: none;
}

#main-nav .nav-crumb { color: var(--color-text-inactive); }
#main-nav .nav-crumb a { color: var(--color-text); }

#main-nav .logo-text { display: inline-flex; align-items: center; gap: 0.3em; }
#main-nav .logo-link { display: inline-flex; align-items: center; gap: 0.3em; padding: 0.3em 0.7em; border: 1px solid var(--color-border); border-radius: 6px; background: var(--surface); }
#main-nav .logo-link:hover { background: var(--color-bg-light); }

/* ==========================================================================
   6. Forms
   ========================================================================== */

form {
  margin-bottom: 1rem;
}

.form-group {
  margin-bottom: 1rem;
}

label {
  display: block;
  margin-bottom: 0.5rem;
  font-weight: 500;
}

input,
textarea,
select,
button {
  box-sizing: border-box;
  font: inherit;
  color: inherit;
  margin: 0;
  padding: 0.5em;
  border: 1px solid var(--color-border);
  background-color: var(--surface);
  line-height: 1.2;
  border-radius: 4px;
}

input[type="text"],
input[type="number"],
input[type="date"],
input[type="email"],
input[type="password"],
select {
  padding: 0.5em;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  box-sizing: border-box;
}

.form-control {
  display: block;
  width: 100%;
  padding: 0.375rem 0.75rem;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--color-text);
  background-color: var(--surface);
  border: 1px solid var(--color-border-light);
  border-radius: 0.25rem;
}

.form-select {
  display: block;
  width: 100%;
  padding: 0.375rem 0.75rem;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--color-text);
  background-color: var(--surface);
  border: 1px solid var(--color-border-light);
  border-radius: 0.25rem;
}

.form-check {
  display: block;
  min-height: 1.5rem;
  margin-bottom: 0.5rem;
}

.form-check-input {
  margin-right: 0.5rem;
}

.form-check-label {
  display: inline-block;
}

.form-label {
  display: block;
  margin-bottom: 0.5rem;
  font-weight: 500;
}

.form-text {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.875rem;
  color: var(--color-text-muted);
}

.form-switch .form-check-input {
  appearance: none;
  width: 2em;
  height: 1em;
  background-color: var(--color-border);
  border-radius: 1em;
  position: relative;
  cursor: pointer;
  border: none;
  padding: 0;
  vertical-align: middle;
}

.form-switch .form-check-input::before {
  content: "";
  position: absolute;
  top: 0.1em;
  left: 0.1em;
  width: 0.8em;
  height: 0.8em;
  background-color: var(--surface);
  border-radius: 50%;
  transition: transform 0.15s ease-in-out;
}

.form-switch .form-check-input:checked {
  background-color: var(--color-primary);
}

.form-switch .form-check-input:checked::before {
  transform: translateX(1em);
}

/* Focusing a radio or a checkbox draws a dotted box around its label —
   the choice reads as a whole line, not a lone control. */
input[type="checkbox"]:focus-visible + label,
input[type="radio"]:focus-visible + label,
label:has(input[type="checkbox"]:focus-visible),
label:has(input[type="radio"]:focus-visible) {
  outline: 1px dotted currentColor;
  outline-offset: 2px;
}

/* The label carries the ring, so the control itself doesn't repeat it. */
input[type="checkbox"]:focus-visible:has(+ label),
input[type="radio"]:focus-visible:has(+ label),
label input[type="checkbox"]:focus-visible,
label input[type="radio"]:focus-visible {
  outline: none;
}

/* A switch is its own visible control — the pill keeps the ring. */
.form-switch .form-check-input:focus-visible {
  outline: 1px dotted currentColor;
  outline-offset: 2px;
}

.form-switch .form-check-input:focus-visible + .form-check-label {
  outline: none;
}

/* ==========================================================================
   7. Buttons
   ========================================================================== */

button {
  cursor: pointer;
}

.btn {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: 0.03em;
  text-align: center;
  vertical-align: middle;
  cursor: pointer;
  padding: 0.4rem 0.85rem;
  font-size: 0.95rem;
  line-height: 1.5;
  border-radius: 2px;
  transition: transform 0.05s ease, background-color 0.15s ease;
  text-decoration: none;
}

.btn:hover {
  text-decoration: none;
}

.btn:active {
  transform: translateY(1px);
}

.btn-primary {
  background-color: var(--color-primary);
  border: 1px solid var(--ink);
  color: var(--on-accent);
}

.btn-primary:hover {
  background-color: var(--accent-hover);
}

.btn-outline {
  background-color: transparent;
  border: 1px solid var(--color-border-light);
}

.btn-outline:hover {
  background-color: var(--color-bg-light);
}

.btn-sm {
  padding: 0.25rem 0.5rem;
  font-size: 0.875rem;
}

.btn-lg {
  padding: 0.5rem 1rem;
  font-size: 1.125rem;
}

.btn-danger {
  background-color: var(--color-error);
  border: 1px solid var(--color-error);
  color: var(--on-error);
}

.btn-warning {
  background-color: var(--color-warning);
  border: 1px solid var(--color-warning);
  color: var(--on-warning);
}

.btn-outline-primary {
  background-color: transparent;
  border: 1px solid var(--color-primary);
  color: var(--color-primary);
}

.btn-outline-primary:hover {
  background-color: var(--color-primary);
  color: var(--on-accent);
}

.btn-outline-secondary {
  background-color: transparent;
  border: 1px solid var(--color-border);
  color: var(--color-text-muted);
}

.btn-outline-secondary:hover {
  background-color: var(--color-bg-light);
  color: var(--color-text);
}

.btn-outline-danger {
  background-color: transparent;
  border: 1px solid var(--color-error);
  color: var(--color-error);
}

.btn-outline-danger:hover {
  background-color: var(--color-error);
  color: var(--on-error);
}

.btn-outline-success {
  background-color: transparent;
  border: 1px solid var(--color-success);
  color: var(--color-success);
}

.btn-outline-success:hover {
  background-color: var(--color-success);
  color: var(--on-success);
}

.btn-block {
  display: block;
  width: 100%;
}

.btn-group {
  display: inline-flex;
}

.btn-group .btn {
  border-radius: 0;
}

.btn-group .btn:first-child {
  border-radius: 0.25rem 0 0 0.25rem;
}

.btn-group .btn:last-child {
  border-radius: 0 0.25rem 0.25rem 0;
}

/* ==========================================================================
   8. Lists
   ========================================================================== */

.list-unstyled {
  list-style: none;
  padding-left: 0;
}

.list-group {
  display: flex;
  flex-direction: column;
  padding: 0;
  margin-bottom: 1rem;
  border: 1px solid var(--color-border-light);
  border-radius: 0.25rem;
}

.list-group-flush {
  border: none;
  border-radius: 0;
}

.list-group-item {
  padding: 0.75rem 1.25rem;
  border-bottom: 1px solid var(--color-border-light);
  list-style: none;
}

.list-group-item:last-child {
  border-bottom: 0;
}

.list-group-flush .list-group-item {
  border-left: 0;
  border-right: 0;
  border-radius: 0;
}

.list-group-item-action {
  color: var(--color-text);
  text-decoration: none;
}

.list-group-item-action:hover {
  background-color: var(--color-bg-light);
}

/* ==========================================================================
   9. Tables
   ========================================================================== */

.table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 1rem;
}

.table th,
.table td {
  padding: 0.75rem;
  border-top: 1px solid var(--color-border-light);
  text-align: left;
}

.table thead th {
  border-bottom: 2px solid var(--color-border);
  border-top: none;
}

.table-hover tbody tr:hover {
  background-color: var(--color-bg-light);
}

.table-responsive {
  display: block;
  width: 100%;
  overflow-x: auto;
}

/* ==========================================================================
   10. Alerts
   ========================================================================== */

/* A notice reads like a station board: the line's colour is a band down
   the left edge rather than a tint you have to decode, and the words stay
   in ink. The hairline on the other three sides is the same colour, so a
   notice is one object in one line's livery. */
.alert {
  padding: 0.75rem 1.25rem;
  margin-bottom: 1rem;
  border: 1px solid transparent;
  border-left-width: 6px;
  border-radius: 0.25rem;
}

.alert-success {
  color: var(--color-alert-success-text);
  background-color: var(--color-alert-success-bg);
  border-color: var(--color-alert-success-border);
}

.alert-warning {
  color: var(--color-alert-warning-text);
  background-color: var(--color-alert-warning-bg);
  border-color: var(--color-alert-warning-border);
}

.alert-danger {
  color: var(--color-alert-danger-text);
  background-color: var(--color-alert-danger-bg);
  border-color: var(--color-alert-danger-border);
}

.alert-info {
  color: var(--color-alert-info-text);
  background-color: var(--color-alert-info-bg);
  border-color: var(--color-alert-info-border);
}

.alert-secondary {
  color: var(--color-alert-secondary-text);
  background-color: var(--color-alert-secondary-bg);
  border-color: var(--color-alert-secondary-border);
}

.alert-heading {
  margin-bottom: 0.5rem;
  font-weight: 600;
}

#flash-messages {
  position: fixed;
  top: 0.5em;
  left: 50%;
  transform: translateX(-50%);
  width: calc(100% - 4em);
  max-width: calc(600px - 4em);
  z-index: 1000;
}

.flash-message {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.5rem;
}

.flash-close {
  background: none;
  border: none;
  padding: 0 0 0 1rem;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0.5;
  border-radius: 0;
  flex-shrink: 0;
}

.flash-close:hover {
  opacity: 1;
}

/* Inline warning box */
.warning-box {
  background-color: var(--color-alert-warning-bg);
  border: 1px solid var(--color-alert-warning-border);
  padding: 1em;
  margin-bottom: 1em;
}

.warning-box h3 {
  margin-top: 0;
}

/* ==========================================================================
   11. Badges
   ========================================================================== */

.badge {
  display: inline-block;
  padding: 0.25em 0.5em;
  font-size: 0.75rem;
  font-weight: 600;
  border-radius: 0.25rem;
}

.bg-light {
  background-color: var(--color-bg-light);
}

.bg-secondary {
  background-color: var(--color-text-muted);
  color: var(--paper);
}

.bg-success {
  background-color: var(--color-success);
  color: var(--on-success);
}

.bg-danger {
  background-color: var(--color-error);
  color: var(--on-error);
}

/* ==========================================================================
   12. Status Indicators
   ========================================================================== */

.status-on-track {
  color: var(--color-success);
}

.status-slightly-behind {
  color: var(--color-warning);
}

.status-behind {
  color: var(--color-error);
}

/* ==========================================================================
   13. Footer
   ========================================================================== */

footer {
  margin-top: auto;
  padding-top: 1em;
  font-size: 0.8rem;
}

/* ==========================================================================
   14. Utility Classes
   ========================================================================== */

/* Text Alignment */
.text-center { text-align: center; }
.text-right { text-align: right; }
.text-end { text-align: right; }

/* Text Colors */
.text-success { color: var(--color-success); }
.text-danger { color: var(--color-error); }
.text-warning { color: var(--color-warning); }
.text-info { color: var(--color-info); }
.text-muted { color: var(--color-text-muted); }
.text-dark { color: var(--color-text); }
.text-inactive { color: var(--color-text-inactive); }

/* Display */
.d-flex { display: flex; }
.d-grid { display: grid; }
.d-block { display: block; }
.d-inline { display: inline; }
.d-inline-block { display: inline-block; }
.d-none { display: none; }

/* Flexbox */
.justify-content-between { justify-content: space-between; }
.justify-content-center { justify-content: center; }
.align-items-center { align-items: center; }
.flex-wrap { flex-wrap: wrap; }
.gap-1 { gap: 0.25rem; }
.gap-2 { gap: 0.5rem; }
.gap-3 { gap: 1rem; }

/* Margins */
.mb-0 { margin-bottom: 0; }
.mb-1 { margin-bottom: 0.25rem; }
.mb-2 { margin-bottom: 0.5rem; }
.mb-3 { margin-bottom: 1rem; }
.mb-4 { margin-bottom: 1.5rem; }
.mb-5 { margin-bottom: 3rem; }

.mt-0 { margin-top: 0; }
.mt-1 { margin-top: 0.25rem; }
.mt-2 { margin-top: 0.5rem; }
.mt-3 { margin-top: 1rem; }
.mt-4 { margin-top: 1.5rem; }
.mt-5 { margin-top: 3rem; }

.me-1 { margin-right: 0.25rem; }
.me-2 { margin-right: 0.5rem; }
.me-3 { margin-right: 1rem; }

.ms-1 { margin-left: 0.25rem; }
.ms-2 { margin-left: 0.5rem; }
.ms-3 { margin-left: 1rem; }

/* Padding */
.p-0 { padding: 0; }
.p-1 { padding: 0.25rem; }
.p-2 { padding: 0.5rem; }
.p-3 { padding: 1rem; }

.py-1 { padding-top: 0.25rem; padding-bottom: 0.25rem; }
.py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
.py-3 { padding-top: 1rem; padding-bottom: 1rem; }

.px-1 { padding-left: 0.25rem; padding-right: 0.25rem; }
.px-2 { padding-left: 0.5rem; padding-right: 0.5rem; }
.pb-4 { padding-bottom: 1.5rem; }
.pt-4 { padding-top: 1.5rem; }
.py-4 { padding-top: 1.5rem; padding-bottom: 1.5rem; }

.px-3 { padding-left: 1rem; padding-right: 1rem; }

/* Width */
.w-100 { width: 100%; }

/* Height */
.h-100 { height: 100%; }

/* Borders */
.border { border: 1px solid var(--color-border-light); }
.border-top { border-top: 1px solid var(--color-border-light); }
.border-bottom { border-bottom: 1px solid var(--color-border-light); }
.border-secondary { border-color: var(--color-text-muted); }
.rounded { border-radius: 0.25rem; }

/* Visibility */
.visually-hidden,
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Typography */
.small { font-size: 0.875rem; }

/* Spinners */
.spinner-border {
  display: inline-block;
  width: 2rem;
  height: 2rem;
  border: 0.25em solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 0.75s linear infinite;
}

.spinner-border-sm {
  width: 1rem;
  height: 1rem;
  border-width: 0.2em;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.text-peach { color: var(--color-primary); }

/* ==========================================================================
   15. JS Toggle (Collapse)
   ========================================================================== */

.collapse {
  display: none;
}

.collapse.show {
  display: block;
}

/* ==========================================================================
   16. Paper chrome — wordmark, rubber stamps, dither rules
   ========================================================================== */

/* Wordmark in the ledger's display face */
#main-nav .logo-text,
#main-nav .logo-link {
  font-family: var(--font-display);
  font-variant: small-caps;
  letter-spacing: 0.05em;
  font-size: 1.05em;
  font-weight: 700;
  filter: grayscale(1);
}

#main-nav .logo-link {
  border-color: var(--rule);
  background: var(--paper-2);
  padding: 0.3em 0.7em 0.5em;
  transition: background 0.12s ease;
}

#main-nav .logo-link:hover {
  background: var(--paper);
}

/* Point at the wordmark and the squirrel goes foraging: a dart left to sniff
   one out, a scurry right to stash it, then an ecstatic little shimmy over the
   size of the hoard. The emoji carries its own element (.logo-squirrel) so the
   wordmark beside it never moves, and so the greyscale can lift off the animal
   alone — an ecstatic rat is in colour. Pivot at the feet, not the middle, or
   the hops read as spins. */
#main-nav .logo-text .logo-squirrel,
#main-nav .logo-link .logo-squirrel {
  display: inline-block;
  transform-origin: 50% 90%;
}

#main-nav .logo-text:hover,
#main-nav .logo-link:hover {
  filter: none;
}

/* ...but the lettering stays exactly as inked as it was: the greyscale it just
   lost with the parent is handed straight back to it. */
#main-nav .logo-text:hover .logo-word,
#main-nav .logo-link:hover .logo-word {
  filter: grayscale(1);
}

#main-nav .logo-text:hover .logo-squirrel,
#main-nav .logo-link:hover .logo-squirrel {
  animation: squirrel-forage 1.1s ease-in-out infinite;
}

@keyframes squirrel-forage {
  0%   { transform: translate(0, 0) rotate(0deg) scale(1); }
  8%   { transform: translate(-0.18em, 0) rotate(-12deg) scale(1); }
  16%  { transform: translate(-0.2em, 0.04em) rotate(-16deg) scale(0.94); }
  24%  { transform: translate(-0.12em, -0.24em) rotate(-4deg) scale(1.06); }
  36%  { transform: translate(0.18em, -0.06em) rotate(10deg) scale(1); }
  44%  { transform: translate(0.2em, 0.04em) rotate(14deg) scale(0.94); }
  54%  { transform: translate(0, -0.1em) rotate(0deg) scale(1.12); }
  64%  { transform: translate(0, -0.34em) rotate(-6deg) scale(1.18); }
  72%  { transform: translate(0, 0) rotate(0deg) scale(0.96); }
  80%  { transform: translate(0, -0.18em) rotate(12deg) scale(1.1); }
  88%  { transform: translate(0, -0.05em) rotate(-10deg) scale(1.06); }
  100% { transform: translate(0, 0) rotate(0deg) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  #main-nav .logo-text:hover .logo-squirrel,
  #main-nav .logo-link:hover .logo-squirrel {
    animation: none;
  }
}

/* Dithered / inked horizontal rule — a halftone strip */
hr {
  height: 4px;
  border: 0;
  margin: 1em 0;
  background: repeating-conic-gradient(var(--ink-soft) 0 25%, transparent 0 50%) 0 0 / 4px 4px;
  opacity: 0.6;
}

/* Rubber stamps — bureaucratic status marks */
.stamp {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 0.72em;
  line-height: 1;
  padding: 0.3em 0.55em;
  border: 2px solid currentColor;
  border-radius: 3px;
  color: var(--ink-soft);
  transform: rotate(-4deg);
  opacity: 0.9;
  box-shadow: inset 0 0 0 1px var(--paper);
  white-space: nowrap;
}

.stamp--ok     { color: var(--color-success); }
.stamp--warn   { color: var(--color-warning); }
.stamp--urgent { color: var(--color-red); transform: rotate(-7deg); }
.stamp--due    { color: var(--accent); }
.stamp--paid   { color: var(--color-success); }

/* Paper filing card (obligations, etc.) */
.owe-card {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1em;
  border: 1px solid var(--rule);
  background: var(--paper-2);
  padding: 0.9em 1em;
  margin-bottom: 0.6em;
}

.owe-card .owe-body { min-width: 0; }
.owe-card .owe-actions { font-size: 0.85em; white-space: nowrap; }



/* Site footer: the legal pages, kept quiet but always reachable. Nothing is
   drawn above them — the space alone is the separation, so the page ends
   rather than being closed off. No auto side margins either: they would stop
   the footer stretching in the body's flex column, shrink-wrapping it around
   the two links and pulling them off centre. Full width, centred contents. */
#site-footer {
  margin: 3em 0 1.5em;
  padding-top: 1em;
  text-align: center;
  font-size: 0.85em;
}

#site-footer a {
  color: var(--color-text-light);
  text-decoration: none;
  margin: 0 0.75em;
}

#site-footer a:hover {
  color: var(--color-text);
  text-decoration: underline;
}
