/* ==========================================================================
   Thread Together Volunteer Hub

   Material Design 3 as the interface system, skinned with Thread Together's
   brand. The colour roles are generated from their teal with Material's own
   colour utilities; the type scale, shape scale, state layers and elevation
   levels are the published M3 values, not approximations.

   Two deliberate departures from stock M3:

   1. The ground is white and the neutrals are a true grey ramp (chroma 0).
      M3 normally tints neutrals from the source colour, which would put a
      teal cast on every surface; an earlier pass used a warm off-white to
      echo the website. Both read as a colour rather than as paper. White it
      is, with the greys reserved for the panels stacked on it.
   2. Primary is tone 48 rather than the usual 40. Tone 40 is a deeper teal
      than their brand and would fight the logo sitting next to it. Tone 48 is
      4.82:1 against white, so it still carries white button labels.

   Availability (open / nearly / full / cancelled) uses custom success and
   warning roles rather than M3's primary-secondary-tertiary, because those
   express emphasis, not status, and a volunteer reading "2 places left" is
   being told a fact about the world rather than where to look.
   ========================================================================== */

:root {
  color-scheme: light dark;

  /* Generated from Thread Together's teal with Material's own colour
     utilities — content palettes, so the source chroma survives instead of
     being boosted to Material's default 48 and turning Google-blue. The
     neutrals are deliberately not derived from it: see note 1 above. */
  --md-primary: #1e7d8a;
  --md-on-primary: #ffffff;
  --md-primary-container: #c9e8ee;
  --md-on-primary-container: #001f24;
  --md-secondary: #516164;
  --md-on-secondary: #ffffff;
  --md-secondary-container: #d4e6e9;
  --md-on-secondary-container: #0e1e21;
  --md-tertiary: #8b4e39;
  --md-on-tertiary: #ffffff;
  --md-tertiary-container: #ffe2d9;
  --md-on-tertiary-container: #370e01;
  --md-error: #b62419;
  --md-on-error: #ffffff;
  --md-error-container: #ffe2dd;
  --md-on-error-container: #410000;
  --md-success: #00673c; --md-on-success: #ffffff;
  --md-success-container: #daf1dd;
  --md-on-success-container: #002110;
  --md-warning: #7e4f00; --md-on-warning: #ffffff;
  --md-warning-container: #ffe7cf;
  --md-on-warning-container: #2a1700;
  --md-surface: #ffffff;
  --md-on-surface: #1b1b1b;
  --md-surface-variant: #e8e8e8;
  --md-on-surface-variant: #474747;
  --md-surface-container-lowest: #ffffff;
  --md-surface-container-low: #f6f6f6;
  --md-surface-container: #f1f1f1;
  --md-surface-container-high: #ebebeb;
  --md-surface-container-highest: #e2e2e2;
  --md-outline: #777777;
  --md-outline-variant: #c6c6c6;
  --md-inverse-surface: #303030;
  --md-inverse-on-surface: #f1f1f1;
  --md-inverse-primary: #80d3e1;

  /* ---- type ---------------------------------------------------------------
     M3 splits the typeface into "brand" (display, headline) and "plain" (title,
     body, label). Franklin Gothic Condensed and Gotham are licensed per-domain,
     so these are the closest Google faces available: Roboto for the display
     voice, Montserrat for the geometric body. */
  --md-font-brand: "Roboto", system-ui, -apple-system, "Segoe UI", sans-serif;
  --md-font-plain: "Montserrat", system-ui, -apple-system, "Segoe UI", sans-serif;
  --md-font-mono:  "Roboto Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --md-display-large:   400 3.5625rem/4rem var(--md-font-brand);
  --md-display-small:   400 2.25rem/2.75rem var(--md-font-brand);
  --md-headline-large:  400 2rem/2.5rem var(--md-font-brand);
  --md-headline-medium: 500 1.75rem/2.25rem var(--md-font-brand);
  --md-headline-small:  500 1.5rem/2rem var(--md-font-brand);
  --md-title-large:     400 1.375rem/1.75rem var(--md-font-plain);
  --md-title-medium:    500 1rem/1.5rem var(--md-font-plain);
  --md-title-small:     500 .875rem/1.25rem var(--md-font-plain);
  --md-body-large:      400 1rem/1.5rem var(--md-font-plain);
  --md-body-medium:     400 .875rem/1.25rem var(--md-font-plain);
  --md-body-small:      400 .75rem/1rem var(--md-font-plain);
  --md-label-large:     500 .875rem/1.25rem var(--md-font-plain);
  --md-label-medium:    500 .75rem/1rem var(--md-font-plain);
  --md-label-small:     500 .6875rem/1rem var(--md-font-plain);

  --md-tracking-body-large:  .03125rem;
  --md-tracking-body-medium: .015625rem;
  --md-tracking-label-large: .00625rem;
  --md-tracking-label-medium:.03125rem;

  /* ---- shape (M3 corner scale) ------------------------------------------- */
  --md-corner-xs: 4px;  --md-corner-sm: 8px;  --md-corner-md: 12px;
  --md-corner-lg: 16px; --md-corner-xl: 28px; --md-corner-full: 9999px;

  /* ---- state layers ------------------------------------------------------ */
  --md-state-hover: .08; --md-state-focus: .12;
  --md-state-press: .12; --md-state-drag: .16;

  /* ---- elevation --------------------------------------------------------- */
  --md-elev-0: none;
  --md-elev-1: 0 1px 2px rgba(0,0,0,.30), 0 1px 3px 1px rgba(0,0,0,.15);
  --md-elev-2: 0 1px 2px rgba(0,0,0,.30), 0 2px 6px 2px rgba(0,0,0,.15);
  --md-elev-3: 0 1px 3px rgba(0,0,0,.30), 0 4px 8px 3px rgba(0,0,0,.15);
  --md-elev-4: 0 2px 3px rgba(0,0,0,.30), 0 6px 10px 4px rgba(0,0,0,.15);
  --md-elev-5: 0 4px 4px rgba(0,0,0,.30), 0 8px 12px 6px rgba(0,0,0,.15);

  /* ---- motion ------------------------------------------------------------ */
  --md-ease: cubic-bezier(.2, 0, 0, 1);
  --md-ease-accel: cubic-bezier(.3, 0, 1, 1);
  --md-dur-short: 100ms; --md-dur-med: 200ms; --md-dur-long: 400ms;

  /* ---- 4dp spacing grid -------------------------------------------------- */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-10: 40px;

  /* ---- aliases ------------------------------------------------------------
     The app's markup predates this system. Rather than rename every class,
     the old token names now resolve to M3 roles, so anything not restyled
     below still lands in the right palette instead of falling back to black. */
  --paper: var(--md-surface);        --surface: var(--md-surface-container-lowest);
  --surface-2: var(--md-surface-container-low);
  --ink: var(--md-on-surface);       --ink-2: var(--md-on-surface-variant);
  --ink-3: var(--md-outline);
  --line: var(--md-outline-variant); --line-2: var(--md-outline);
  --brand: var(--md-primary);        --brand-ink: var(--md-on-primary);
  --brand-tint: var(--md-primary);
  --brand-soft: var(--md-primary-container); --brand-line: var(--md-primary);
  --accent: var(--md-tertiary);      --accent-soft: var(--md-tertiary-container);
  --ok: var(--md-success);   --ok-soft: var(--md-success-container);
  --warn: var(--md-warning); --warn-soft: var(--md-warning-container);
  --stop: var(--md-error);   --stop-soft: var(--md-error-container);
  --full: var(--md-on-surface-variant); --full-soft: var(--md-surface-variant);
  --shadow: var(--md-elev-1); --shadow-l: var(--md-elev-3);
  --r: var(--md-corner-sm); --r-l: var(--md-corner-md);
  --sans: var(--md-font-plain); --mono: var(--md-font-mono);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
--md-primary: #80d3e1;
    --md-on-primary: #00363d;
    --md-primary-container: #004f58;
    --md-on-primary-container: #c9e8ee;
    --md-secondary: #b8cacd;
    --md-on-secondary: #233336;
    --md-secondary-container: #39494c;
    --md-on-secondary-container: #d4e6e9;
    --md-tertiary: #ffb59b;
    --md-on-tertiary: #522210;
    --md-tertiary-container: #6e3823;
    --md-on-tertiary-container: #ffdbcf;
    --md-error: #ffb4a8;
    --md-on-error: #690001;
    --md-error-container: #5d3f3b;
    --md-on-error-container: #ffdad5;
    --md-success: #79da9e; --md-on-success: #00391f;
    --md-success-container: #2e4234;
    --md-on-success-container: #d1e8d5;
    --md-warning: #fcba65; --md-on-warning: #442b00;
    --md-warning-container: #4f3a1f;
    --md-on-warning-container: #ffddb8;
    --md-surface: #131313;
    --md-on-surface: #e2e2e2;
    --md-surface-variant: #474747;
    --md-on-surface-variant: #c6c6c6;
    --md-surface-container-lowest: #0e0e0e;
    --md-surface-container-low: #1b1b1b;
    --md-surface-container: #1f1f1f;
    --md-surface-container-high: #2a2a2a;
    --md-surface-container-highest: #353535;
    --md-outline: #919191;
    --md-outline-variant: #474747;
    --md-inverse-surface: #e2e2e2;
    --md-inverse-on-surface: #303030;
    --md-inverse-primary: #1e7d8a;
  }
}
:root[data-theme="dark"] {
--md-primary: #80d3e1;
    --md-on-primary: #00363d;
    --md-primary-container: #004f58;
    --md-on-primary-container: #c9e8ee;
    --md-secondary: #b8cacd;
    --md-on-secondary: #233336;
    --md-secondary-container: #39494c;
    --md-on-secondary-container: #d4e6e9;
    --md-tertiary: #ffb59b;
    --md-on-tertiary: #522210;
    --md-tertiary-container: #6e3823;
    --md-on-tertiary-container: #ffdbcf;
    --md-error: #ffb4a8;
    --md-on-error: #690001;
    --md-error-container: #5d3f3b;
    --md-on-error-container: #ffdad5;
    --md-success: #79da9e; --md-on-success: #00391f;
    --md-success-container: #2e4234;
    --md-on-success-container: #d1e8d5;
    --md-warning: #fcba65; --md-on-warning: #442b00;
    --md-warning-container: #4f3a1f;
    --md-on-warning-container: #ffddb8;
    --md-surface: #131313;
    --md-on-surface: #e2e2e2;
    --md-surface-variant: #474747;
    --md-on-surface-variant: #c6c6c6;
    --md-surface-container-lowest: #0e0e0e;
    --md-surface-container-low: #1b1b1b;
    --md-surface-container: #1f1f1f;
    --md-surface-container-high: #2a2a2a;
    --md-surface-container-highest: #353535;
    --md-outline: #919191;
    --md-outline-variant: #474747;
    --md-inverse-surface: #e2e2e2;
    --md-inverse-on-surface: #303030;
    --md-inverse-primary: #1e7d8a;
}

/* ==========================================================================
   Base
   ========================================================================== */

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--md-surface);
  color: var(--md-on-surface);
  font: var(--md-body-large);
  letter-spacing: var(--md-tracking-body-large);
  -webkit-font-smoothing: antialiased;
}
p { margin: 0; }
button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
a { color: var(--md-primary); text-underline-offset: 2px; }

h1, h2, h3 {
  margin: 0; text-wrap: balance;
  font-family: var(--md-font-brand); font-weight: 600; letter-spacing: 0;
}

/* M3 focus: a 3:1 ring, never removed, never only a colour change. */
:focus-visible {
  outline: 3px solid var(--md-primary); outline-offset: 2px;
  border-radius: var(--md-corner-xs);
}

/* The state layer. M3 expresses hover/focus/press as a translucent wash of the
   foreground colour over the component, not as a different colour — so one rule
   drives every interactive surface and nothing is ever hover-only. */
.btn, .chip, .nav a, .seg button, .places button, .dx, .card.click, .person {
  position: relative; isolation: isolate;
}
.btn::after, .chip::after, .nav a::after, .seg button::after,
.places button::after, .dx::after, .card.click::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: currentColor; opacity: 0; pointer-events: none; z-index: -1;
  transition: opacity var(--md-dur-short) var(--md-ease);
}
.btn:hover::after, .chip:hover::after, .nav a:hover::after, .seg button:hover::after,
.places button:hover::after, .dx:hover::after, .card.click:hover::after { opacity: var(--md-state-hover); }
.btn:active::after, .chip:active::after, .seg button:active::after,
.places button:active::after, .card.click:active::after { opacity: var(--md-state-press); }

.label {
  font: var(--md-label-medium); letter-spacing: .08em;
  text-transform: uppercase; color: var(--md-on-surface-variant);
}
.mono  { font-family: var(--md-font-mono); font-variant-numeric: tabular-nums; }
.muted { color: var(--md-on-surface-variant); }
.hide  { display: none !important; }

/* ==========================================================================
   App chrome — top app bar and primary tabs
   ========================================================================== */

.topbar {
  background: var(--md-surface); position: sticky; top: 0; z-index: 40;
}
.topbar-in {
  max-width: 1080px; margin: 0 auto; min-height: 64px;
  padding: var(--sp-2) var(--sp-4); display: flex; align-items: center; gap: var(--sp-4);
}
.brand { display: inline-flex; align-items: center; gap: var(--sp-3); color: var(--md-primary); }
.brand > span {
  font: var(--md-title-small); color: var(--md-on-surface-variant);
  padding-left: var(--sp-3); border-left: 1px solid var(--md-outline-variant);
  letter-spacing: var(--md-tracking-label-large); text-transform: none;
}

.who { margin-left: auto; display: flex; align-items: center; gap: var(--sp-3); font: var(--md-body-medium); }
.who .nm { color: var(--md-on-surface-variant); }
@media (max-width: 560px) { .who .nm { display: none; } }

/* M3 primary tabs: 48dp, label-large, 3dp indicator with a rounded top. */
.nav {
  background: var(--md-surface); position: sticky; top: 64px; z-index: 39;
  box-shadow: inset 0 -1px 0 var(--md-outline-variant);
}
.nav-in { max-width: 1080px; margin: 0 auto; padding: 0 var(--sp-4); display: flex; overflow-x: auto; }
.nav-in::-webkit-scrollbar { height: 0; }
.nav a {
  display: flex; align-items: center; min-height: 48px; padding: 0 var(--sp-4);
  font: var(--md-title-small); letter-spacing: var(--md-tracking-label-large);
  color: var(--md-on-surface-variant); text-decoration: none; white-space: nowrap;
  border-bottom: 3px solid transparent; border-radius: var(--md-corner-sm) var(--md-corner-sm) 0 0;
  transition: color var(--md-dur-short) var(--md-ease);
}
.nav a:hover { color: var(--md-on-surface); }
.nav a.on { color: var(--md-primary); border-bottom-color: var(--md-primary); }
.nav .nav-ico, .nav .nav-lbl-s { display: none; }

/* ---- M3 navigation bar --------------------------------------------------
   Below 720px the volunteer's four destinations move off the top tab row and
   into a navigation bar at the bottom of the screen, where a thumb can reach
   them. Icons are inline SVG (see NAV_ICON in app.js). Admins are excluded:
   seven destinations do not fit a bar, and admin work happens at a desk. */
@media (max-width: 720px) {
  .nav.bar {
    position: fixed; top: auto; left: 0; right: 0; bottom: 0; z-index: 45;
    background: var(--md-surface-container);
    box-shadow: inset 0 1px 0 var(--md-outline-variant);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .nav.bar .nav-in { padding: 0; overflow: visible; }
  .nav.bar a {
    flex: 1 1 0; min-width: 0; flex-direction: column; justify-content: center;
    gap: var(--sp-1); padding: var(--sp-3) var(--sp-1) var(--sp-4);
    min-height: 80px; border-bottom: none; border-radius: 0;
    font: var(--md-label-medium); letter-spacing: var(--md-tracking-label-medium);
    color: var(--md-on-surface-variant);
  }
  .nav.bar a.on { color: var(--md-on-surface); }
  .nav.bar .nav-lbl { display: none; }
  .nav.bar .nav-lbl-s {
    display: block; max-width: 100%; overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap; text-align: center;
  }
  /* The active indicator: a 64×32 pill behind the icon, per M3. */
  .nav.bar .nav-ico {
    display: block; width: 24px; height: 24px; fill: currentColor;
    box-sizing: content-box; padding: 4px 20px; border-radius: var(--md-corner-full);
    transition: background var(--md-dur-short) var(--md-ease);
  }
  .nav.bar a.on .nav-ico {
    background: var(--md-secondary-container); color: var(--md-on-secondary-container);
  }
  /* Clear the bar so the last row of a list is never trapped under it. */
  .wrap.has-bar { padding-bottom: calc(96px + env(safe-area-inset-bottom, 0px)); }
}

.wrap { max-width: 1080px; margin: 0 auto; padding: var(--sp-6) var(--sp-4) 80px; }
.wrap.narrow { max-width: 640px; }

.page-head { margin-bottom: var(--sp-6); display: flex; align-items: flex-end; gap: var(--sp-4); flex-wrap: wrap; }
.page-head h1 { font: var(--md-headline-medium); font-family: var(--md-font-brand); }
.page-head p { color: var(--md-on-surface-variant); font: var(--md-body-medium);
                letter-spacing: var(--md-tracking-body-medium); margin-top: var(--sp-1); }
.page-head .actions { margin-left: auto; display: flex; gap: var(--sp-2); }

/* ==========================================================================
   Buttons — M3 filled, outlined and text
   ========================================================================== */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 40px; padding: 0 var(--sp-6);
  border: none; border-radius: var(--md-corner-full); cursor: pointer;
  background: var(--md-primary); color: var(--md-on-primary);
  font: var(--md-label-large); letter-spacing: var(--md-tracking-label-large);
  text-decoration: none; white-space: nowrap;
  transition: box-shadow var(--md-dur-short) var(--md-ease);
}
.btn:disabled {
  background: color-mix(in srgb, var(--md-on-surface) 12%, transparent);
  color: color-mix(in srgb, var(--md-on-surface) 38%, transparent);
  cursor: not-allowed;
}
.btn:disabled::after { opacity: 0; }

.btn.ghost {
  background: transparent; color: var(--md-primary);
  box-shadow: inset 0 0 0 1px var(--md-outline);
}
.btn.danger {
  background: transparent; color: var(--md-error);
  box-shadow: inset 0 0 0 1px var(--md-error);
}
.btn.text { background: transparent; color: var(--md-primary); padding: 0 var(--sp-3); }
.btn.sm { min-height: 32px; padding: 0 var(--sp-4); font: var(--md-label-medium); }
.btn.block { width: 100%; }

/* ==========================================================================
   Filter chips
   ========================================================================== */

.chips { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-5); }
.chip {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-height: 32px; padding: 0 var(--sp-4);
  border: none; box-shadow: inset 0 0 0 1px var(--md-outline);
  background: transparent; color: var(--md-on-surface-variant);
  border-radius: var(--md-corner-sm); cursor: pointer;
  font: var(--md-label-large); letter-spacing: var(--md-tracking-label-large);
  white-space: nowrap;
}
.chip[aria-pressed="true"] {
  background: var(--md-secondary-container); color: var(--md-on-secondary-container);
  box-shadow: none; padding-left: var(--sp-2);
}
/* M3 shows selection with a leading check, not only a fill — colour alone is
   not a state anyone can rely on. */
.chip[aria-pressed="true"]::before {
  content: ""; width: 18px; height: 18px; flex: none; background: currentColor;
  -webkit-mask: var(--check) no-repeat center / 18px; mask: var(--check) no-repeat center / 18px;
}
:root { --check: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z' fill='black'/></svg>"); }

/* ==========================================================================
   Opportunity cards — M3 outlined card
   ========================================================================== */

.cards { display: flex; flex-direction: column; gap: var(--sp-3); }
.card {
  display: grid; grid-template-columns: 72px 1fr auto; gap: var(--sp-5); align-items: center;
  padding: var(--sp-4); background: var(--md-surface); color: var(--md-on-surface);
  border-radius: var(--md-corner-md); box-shadow: inset 0 0 0 1px var(--md-outline-variant);
  transition: box-shadow var(--md-dur-med) var(--md-ease);
}
.card.click { cursor: pointer; }
.card.click:hover { box-shadow: inset 0 0 0 1px var(--md-outline-variant), var(--md-elev-1); }

.dt {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: var(--sp-2) 0; background: var(--md-primary-container);
  color: var(--md-on-primary-container); border-radius: var(--md-corner-sm);
}
.dt .dow { font: var(--md-label-small); letter-spacing: .08em; text-transform: uppercase; opacity: .8; }
.dt .d   { font-family: var(--md-font-brand); font-size: 24px; font-weight: 600; line-height: 1.1;
            font-variant-numeric: tabular-nums; }
.dt .m   { font: var(--md-label-small); letter-spacing: .08em; text-transform: uppercase; opacity: .8; }

.cbody { min-width: 0; }
.ctitle { font: var(--md-title-medium); margin-bottom: 2px; }
.cmeta { display: flex; flex-wrap: wrap; gap: 2px var(--sp-2); font: var(--md-body-small);
          letter-spacing: var(--md-tracking-body-medium); color: var(--md-on-surface-variant); }
.cmeta .sep { color: var(--md-outline-variant); }
.cright { display: flex; flex-direction: column; align-items: flex-end; gap: var(--sp-2); }

/* One segment per place: these sessions hold 2-6 people, so "2 of 4" is a
   countable thing and a percentage bar would misrepresent the granularity. */
.meter { display: flex; gap: 3px; }
.meter i { width: 8px; height: 16px; border-radius: 2px;
            background: transparent; box-shadow: inset 0 0 0 1px var(--md-outline); }
.meter i.on { background: var(--md-success); box-shadow: none; }
[data-s="nearly"] .meter i.on { background: var(--md-warning); }
[data-s="full"]   .meter i.on { background: var(--md-on-surface-variant); }

.pill {
  font: var(--md-label-medium); letter-spacing: var(--md-tracking-label-medium);
  padding: var(--sp-1) var(--sp-2); border-radius: var(--md-corner-xs); white-space: nowrap;
}
[data-s="open"]      .pill { background: var(--md-success-container); color: var(--md-on-success-container); }
[data-s="nearly"]    .pill { background: var(--md-warning-container); color: var(--md-on-warning-container); }
[data-s="full"]      .pill { background: var(--md-surface-variant);   color: var(--md-on-surface-variant); }
[data-s="cancelled"] .pill { background: var(--md-error-container);   color: var(--md-on-error-container); }
[data-s="draft"]     .pill { background: var(--md-surface-variant);   color: var(--md-on-surface-variant); }
[data-s="booked"]    .pill { background: var(--md-primary-container); color: var(--md-on-primary-container); }

@media (max-width: 620px) {
  .card { grid-template-columns: 56px 1fr; gap: var(--sp-3); }
  .cright { grid-column: 2; flex-direction: row; align-items: center; gap: var(--sp-3); }
  .dt .d { font-size: 20px; }
}

/* ==========================================================================
   States
   ========================================================================== */

.empty {
  padding: var(--sp-10) var(--sp-5); text-align: center; color: var(--md-on-surface-variant);
  border-radius: var(--md-corner-md); background: var(--md-surface-container-low);
  font: var(--md-body-medium);
}
.empty strong { display: block; color: var(--md-on-surface); font: var(--md-title-medium); margin-bottom: var(--sp-1); }

.note {
  padding: var(--sp-3) var(--sp-4); border-radius: var(--md-corner-sm);
  font: var(--md-body-medium); letter-spacing: var(--md-tracking-body-medium);
  margin-bottom: var(--sp-4);
  background: var(--md-surface-container); color: var(--md-on-surface-variant);
}
.note.ok   { background: var(--md-success-container); color: var(--md-on-success-container); }
.note.warn { background: var(--md-warning-container); color: var(--md-on-warning-container); }
.note.stop { background: var(--md-error-container);   color: var(--md-on-error-container); }
.note b { font-weight: 600; }

.skel {
  height: 80px; border-radius: var(--md-corner-md); background: var(--md-surface-container);
  animation: pulse 1.4s ease-in-out infinite;
}
@keyframes pulse { 0%,100% { opacity: .45; } 50% { opacity: .8; } }

/* ==========================================================================
   Forms — M3 outlined text field
   The label sits in a notch cut through the outline. That is the part that
   makes a form read as Material rather than as a generic web form, and it is
   done with a background swatch on the label, so it needs no JavaScript and
   no change to the markup the app already emits.
   ========================================================================== */

.field { position: relative; margin-bottom: var(--sp-5); }
/* The notch only belongs to fields that actually hold a text control. A field
   wrapping a button group or a checkbox has no outline to cut through, and the
   floating label would hang over the controls. */
.field > label { display: block; margin-bottom: var(--sp-2);
                 font: var(--md-body-small); color: var(--md-on-surface-variant); }
.field:has(> input, > select, > textarea) > label {
  position: absolute; top: -7px; left: 12px; z-index: 1; margin: 0;
  padding: 0 var(--sp-1); background: var(--md-surface);
  letter-spacing: var(--md-tracking-body-medium); pointer-events: none;
}
.field:focus-within > label { color: var(--md-primary); }
.field .hint {
  display: block; margin: var(--sp-1) var(--sp-4) 0;
  font: var(--md-body-small); color: var(--md-on-surface-variant);
}

input, select, textarea {
  width: 100%; min-height: 56px; padding: var(--sp-4);
  background: transparent; color: var(--md-on-surface);
  border: 1px solid var(--md-outline); border-radius: var(--md-corner-xs);
  font: var(--md-body-large); letter-spacing: var(--md-tracking-body-large);
  transition: border-color var(--md-dur-short) var(--md-ease);
}
select { appearance: none; padding-right: var(--sp-8);
  background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M7 10l5 5 5-5z' fill='%23808080'/></svg>");
  background-repeat: no-repeat; background-position: right 10px center; background-size: 22px; }
textarea { resize: vertical; min-height: 96px; }
input:hover, select:hover, textarea:hover { border-color: var(--md-on-surface); }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--md-primary); border-width: 2px; padding: 15px;
}
input[type="checkbox"], input[type="radio"] {
  width: auto; min-height: 0; padding: 0; accent-color: var(--md-primary);
  border: 0; inline-size: 18px; block-size: 18px;
}
.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
@media (max-width: 520px) { .row2 { grid-template-columns: 1fr; gap: 0; } }

.places { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.places button {
  min-width: 56px; min-height: 40px; padding: 0 var(--sp-3);
  border: none; box-shadow: inset 0 0 0 1px var(--md-outline); background: transparent;
  border-radius: var(--md-corner-full); cursor: pointer;
  font: var(--md-label-large); font-variant-numeric: tabular-nums;
  color: var(--md-on-surface-variant);
}
.places button[aria-pressed="true"] {
  background: var(--md-secondary-container); color: var(--md-on-secondary-container); box-shadow: none;
}

.att { display: grid; grid-template-columns: 20px 1fr 1fr; gap: var(--sp-2); align-items: start; margin-bottom: var(--sp-3); }
.att .n { font-family: var(--md-font-mono); font: var(--md-body-small); color: var(--md-on-surface-variant); padding-top: var(--sp-5); }
.att .field { margin-bottom: 0; }
@media (max-width: 520px) { .att { grid-template-columns: 20px 1fr; } }

/* ==========================================================================
   Signed-out screens
   ========================================================================== */

.auth { min-height: 100vh; display: grid; place-items: center; padding: var(--sp-6);
         background: var(--md-surface-container-low); }
.auth-box { width: 100%; max-width: 400px; }
.auth-box.wide { max-width: 560px; }
.auth-brand { text-align: center; margin-bottom: var(--sp-8); color: var(--md-primary); }
.auth-brand .tag { color: var(--md-on-surface-variant); font: var(--md-body-medium); margin-top: var(--sp-2); }
.auth-card {
  background: var(--md-surface); border-radius: var(--md-corner-xl);
  padding: var(--sp-8) var(--sp-6); box-shadow: var(--md-elev-1);
}
.auth-card h1 { font: var(--md-headline-small); font-family: var(--md-font-brand); margin-bottom: var(--sp-2); }
.auth-card > p { color: var(--md-on-surface-variant); font: var(--md-body-medium);
                  letter-spacing: var(--md-tracking-body-medium); margin-bottom: var(--sp-6); }
.auth-alt { text-align: center; margin-top: var(--sp-4); font: var(--md-body-medium); }
.auth-alt button { background: none; border: 0; color: var(--md-primary); cursor: pointer;
                    font: var(--md-label-large); padding: var(--sp-2); text-decoration: underline; }
.auth-foot { text-align: center; margin-top: var(--sp-5); font: var(--md-body-small);
              color: var(--md-on-surface-variant); line-height: 1.6; }
.auth-foot a, .auth-foot button { color: var(--md-primary); background: none; border: 0;
              font: inherit; cursor: pointer; padding: 0; text-decoration: underline; }

/* ==========================================================================
   Dialogs — M3 basic dialog, 28dp corner
   ========================================================================== */

dialog {
  border: none; border-radius: var(--md-corner-xl); padding: 0;
  background: var(--md-surface-container-high); color: var(--md-on-surface);
  width: min(560px, calc(100vw - 48px)); max-height: 88vh; box-shadow: var(--md-elev-3);
}
dialog::backdrop { background: rgba(0,0,0,.32); }
@media (max-width: 620px) {
  dialog { width: 100vw; max-width: 100vw; max-height: 92vh; margin: auto 0 0;
            border-radius: var(--md-corner-xl) var(--md-corner-xl) 0 0; }
}
.dh {
  padding: var(--sp-6) var(--sp-6) var(--sp-4); display: flex; gap: var(--sp-4); align-items: flex-start;
  position: sticky; top: 0; background: var(--md-surface-container-high); z-index: 2;
  border-radius: var(--md-corner-xl) var(--md-corner-xl) 0 0;
}
.dh h2 { font: var(--md-headline-small); font-family: var(--md-font-brand); }
.dh .kicker { font: var(--md-label-medium); letter-spacing: .08em; text-transform: uppercase;
               color: var(--md-on-surface-variant); margin-bottom: var(--sp-1); }
.dx {
  margin-left: auto; flex: none; width: 40px; height: 40px; border: 0;
  background: transparent; border-radius: var(--md-corner-full); cursor: pointer;
  color: var(--md-on-surface-variant); line-height: 1; font-size: 18px;
}
.db { padding: 0 var(--sp-6) var(--sp-4); overflow-y: auto;
       font: var(--md-body-medium); letter-spacing: var(--md-tracking-body-medium); }
.df { padding: var(--sp-4) var(--sp-6) var(--sp-6); display: flex; gap: var(--sp-2);
       align-items: center; position: sticky; bottom: 0;
       background: var(--md-surface-container-high); }
.grow { margin-left: auto; }

.facts { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4) var(--sp-5); margin-bottom: var(--sp-4); }
@media (max-width: 460px) { .facts { grid-template-columns: 1fr; } }
.fact { display: flex; flex-direction: column; gap: 2px; }
.fact .v { font: var(--md-body-large); }

.ref {
  font-family: var(--md-font-mono); font-size: 20px; letter-spacing: .08em;
  padding: var(--sp-3) var(--sp-4); background: var(--md-primary-container);
  color: var(--md-on-primary-container); border-radius: var(--md-corner-sm);
  display: inline-block;
}

/* ==========================================================================
   Tables — M3 data table
   ========================================================================== */

.tw { overflow-x: auto; border-radius: var(--md-corner-md); background: var(--md-surface);
       box-shadow: inset 0 0 0 1px var(--md-outline-variant); }
table { width: 100%; border-collapse: collapse; }
th {
  text-align: left; padding: var(--sp-4); white-space: nowrap;
  font: var(--md-label-medium); letter-spacing: var(--md-tracking-label-medium);
  color: var(--md-on-surface-variant); border-bottom: 1px solid var(--md-outline-variant);
}
td {
  padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--md-outline-variant);
  vertical-align: middle; font: var(--md-body-medium); letter-spacing: var(--md-tracking-body-medium);
}
tr:last-child td { border-bottom: 0; }
td.num, .rate { font-family: var(--md-font-mono); font-variant-numeric: tabular-nums; }

/* ==========================================================================
   Dashboard tiles
   ========================================================================== */

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
          gap: var(--sp-3); margin-bottom: var(--sp-6); }
.tile { background: var(--md-surface-container-low); border-radius: var(--md-corner-md);
         padding: var(--sp-4) var(--sp-5); }
.tile .v { font-family: var(--md-font-brand); font-size: 32px; font-weight: 600;
            font-variant-numeric: tabular-nums; line-height: 1.15; margin-top: var(--sp-1); }
.tile .sub { font: var(--md-body-small); color: var(--md-on-surface-variant); margin-top: 2px; }

/* M3 snackbar */
.toast {
  position: fixed; left: 50%; bottom: var(--sp-6); transform: translateX(-50%);
  background: var(--md-inverse-surface); color: var(--md-inverse-on-surface);
  padding: var(--sp-3) var(--sp-4); border-radius: var(--md-corner-xs);
  font: var(--md-body-medium); box-shadow: var(--md-elev-3); z-index: 100;
  max-width: calc(100vw - 32px);
}
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }

/* ==========================================================================
   Attendance
   Attended / didn't come / not yet marked are STATUS, not categories, so they
   are never distinguished by hue alone. The palette validator measured the
   obvious green-vs-red pairing at ΔE 5.2 under deuteranopia — indistinguishable
   for roughly one man in twelve. Each state therefore also differs in FILL:
   solid, hatched, or hollow. Every figure carries its number in text as well.
   ========================================================================== */

.att-bar {
  display: flex; gap: 2px; height: 12px; border-radius: var(--md-corner-xs); overflow: hidden;
  background: var(--md-surface-variant); min-width: 120px;
}
.att-bar span { display: block; height: 100%; }
.att-bar .a { background: var(--md-success); }
.att-bar .n {
  background: var(--md-error);
  /* Hatch: the CVD-safe half of the encoding, not decoration. */
  background-image: repeating-linear-gradient(45deg,
    rgba(255,255,255,.55) 0 2px, transparent 2px 4px);
}
.att-bar .u { background: transparent; box-shadow: inset 0 0 0 1px var(--md-outline); }

.att-key { display: flex; gap: var(--sp-4); flex-wrap: wrap; font: var(--md-body-small);
            color: var(--md-on-surface-variant); }
.att-key i { width: 12px; height: 12px; border-radius: 3px; display: inline-block;
              vertical-align: -1px; margin-right: var(--sp-1); }
.att-key .a { background: var(--md-success); }
.att-key .n { background: var(--md-error);
  background-image: repeating-linear-gradient(45deg,
    rgba(255,255,255,.55) 0 2px, transparent 2px 4px); }
.att-key .u { background: transparent; box-shadow: inset 0 0 0 1px var(--md-outline); }

[data-a="attended"] .pill { background: var(--md-success-container); color: var(--md-on-success-container); }
[data-a="no_show"]  .pill { background: var(--md-error-container);   color: var(--md-on-error-container); }
[data-a="expected"] .pill { background: var(--md-surface-variant);   color: var(--md-on-surface-variant); }

/* ==========================================================================
   Run sheet
   Used one-handed, on a phone, standing in a church hall. Big targets, high
   contrast, no ambiguity about what has been recorded.
   ========================================================================== */

.run { display: flex; flex-direction: column; gap: var(--sp-2); }
.person {
  display: grid; grid-template-columns: 1fr auto; gap: var(--sp-3); align-items: center;
  padding: var(--sp-3) var(--sp-4); background: var(--md-surface);
  border-radius: var(--md-corner-md); box-shadow: inset 0 0 0 1px var(--md-outline-variant);
}
.person.marked-a { background: var(--md-success-container); box-shadow: none; }
.person.marked-n { background: var(--md-error-container);   box-shadow: none; }
.person .nm { font: var(--md-title-medium); }
.person .sub { font: var(--md-body-small); color: var(--md-on-surface-variant); margin-top: 1px; }
.person .sub .lead { font-weight: 600; }

/* M3 segmented button */
.seg { display: inline-flex; border-radius: var(--md-corner-full); overflow: hidden;
        box-shadow: inset 0 0 0 1px var(--md-outline); }
.seg button {
  border: 0; background: transparent; cursor: pointer;
  padding: 0 var(--sp-4); min-width: 72px; min-height: 40px;
  font: var(--md-label-large); letter-spacing: var(--md-tracking-label-large);
  color: var(--md-on-surface-variant);
}
.seg button + button { box-shadow: inset 1px 0 0 var(--md-outline); }
.seg button[aria-pressed="true"] { background: var(--md-secondary-container); color: var(--md-on-secondary-container); }
.seg button[aria-pressed="true"][data-v="attended"] { background: var(--md-success); color: var(--md-on-success); }
.seg button[aria-pressed="true"][data-v="no_show"]  { background: var(--md-error);   color: var(--md-on-error); }
.seg button:disabled { opacity: .5; cursor: wait; }

@media (max-width: 520px) {
  .person { grid-template-columns: 1fr; gap: var(--sp-3); }
  .seg { width: 100%; }
  .seg button { flex: 1; }
}

.run-head {
  display: flex; gap: var(--sp-3); align-items: center; flex-wrap: wrap;
  padding: var(--sp-4); background: var(--md-surface-container-low);
  border-radius: var(--md-corner-md); margin-bottom: var(--sp-4);
}
.run-head .count { font-family: var(--md-font-brand); font-size: 24px; font-weight: 600; }
.run-head .grow { margin-left: auto; }

.unsaved {
  position: fixed; left: 50%; bottom: var(--sp-6); transform: translateX(-50%);
  background: var(--md-warning-container); color: var(--md-on-warning-container);
  padding: var(--sp-3) var(--sp-4); border-radius: var(--md-corner-xs);
  font: var(--md-label-large); box-shadow: var(--md-elev-3); z-index: 100;
}

/* ==========================================================================
   Reports
   ========================================================================== */

.filters-row {
  display: flex; gap: var(--sp-3); flex-wrap: wrap; align-items: flex-start;
  padding: var(--sp-4) var(--sp-4) var(--sp-2);
  background: var(--md-surface-container-low); border-radius: var(--md-corner-md);
  margin-bottom: var(--sp-5);
}
.filters-row .field { margin-bottom: var(--sp-2); min-width: 170px; }
/* The download belongs beside the filters that decide what is in it, not in
   the page header where it reads as "download the month" whatever is set. */
.filters-row .grow { margin-left: auto; align-self: center; margin-bottom: var(--sp-2); }
@media (max-width: 620px) { .filters-row .grow { margin-left: 0; width: 100%; } }
.filters-row .field > label { background: var(--md-surface-container-low); }
.subtle-head { font: var(--md-title-large); font-family: var(--md-font-brand); margin: var(--sp-8) 0 var(--sp-3); }

/* The run sheet and the reports table are the two things anyone prints. */
@media print {
  .no-print, .topbar, .nav { display: none !important; }
  .wrap { padding: 0; max-width: none; }
  .tile, .tw { break-inside: avoid; }
}

/* ==========================================================================
   Applications waiting
   ========================================================================== */

.applications { margin-bottom: var(--sp-8); }
.applications h2 { font: var(--md-title-large); font-family: var(--md-font-brand); margin-bottom: var(--sp-1); }

.appcard {
  background: var(--md-surface); border-radius: var(--md-corner-md);
  box-shadow: inset 0 0 0 1px var(--md-outline-variant), inset 4px 0 0 var(--md-warning);
  padding: var(--sp-4) var(--sp-5); margin-bottom: var(--sp-3);
}
.appcard.flagged { box-shadow: inset 0 0 0 1px var(--md-outline-variant), inset 4px 0 0 var(--md-error); }
.appcard .ahead { display: flex; gap: var(--sp-4); align-items: flex-start; flex-wrap: wrap; }
.appcard .nm { font: var(--md-title-medium); }
.appcard .sub { font: var(--md-body-small); color: var(--md-on-surface-variant); margin-top: 2px; }
.appcard .sub a { color: var(--md-on-surface-variant); }
.appcard .sub .sep { color: var(--md-outline-variant); }
.appcard .arow { margin-left: auto; display: flex; gap: var(--sp-2); }
.appcard .ameta { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3) var(--sp-5);
                   margin-top: var(--sp-4); font: var(--md-body-medium); }
.appcard .ameta .label { margin-bottom: 2px; }
.appcard .about { margin-top: var(--sp-3); padding: var(--sp-3); background: var(--md-surface-container-low);
                   border-radius: var(--md-corner-sm); font: var(--md-body-medium);
                   color: var(--md-on-surface-variant); white-space: pre-wrap; }
@media (max-width: 520px) { .appcard .ameta { grid-template-columns: 1fr; } .appcard .arow { margin-left: 0; } }

/* ==========================================================================
   Notification preferences and Blue Card standing
   ========================================================================== */

.switch { display: flex; gap: var(--sp-3); align-items: flex-start; font: var(--md-body-medium);
           cursor: pointer; line-height: 1.5; margin-top: var(--sp-1); }
.switch input { width: auto; margin-top: 3px; flex: none; }
.switch b { font-weight: 600; }

.tagline { font: var(--md-label-medium); letter-spacing: var(--md-tracking-label-medium); white-space: nowrap; }
.tagline.ok   { color: var(--md-success); }
.tagline.warn { color: var(--md-warning); }
.tagline.stop { color: var(--md-error); }

/* ==========================================================================
   The wordmark
   Carried as a mask rather than an <img> so it takes currentColor: teal on the
   light theme, pale teal on dark, white if it ever sits on a teal fill. One
   asset, no second request, and no wrong-coloured logo on a dark background.
   ========================================================================== */

.logo-mark {
  --logo: url("data:image/svg+xml,<svg viewBox='0 0 173 58' xmlns='http://www.w3.org/2000/svg'> <path d='M27.7357 56.9054C29.3249 56.8874 30.609 55.4998 30.6246 53.8236L31.0687 6.05201L54.8735 5.74597C55.9451 5.62682 56.7933 4.35126 56.8071 2.87121C56.8208 1.39117 55.9962 0.134604 54.9266 0.0397719L54.776 0.0414818L2.76736 0.632179C1.52946 0.646239 0.513823 1.94154 0.499071 3.52858C0.484319 5.11561 1.47609 6.38811 2.71399 6.37405L12.0484 6.26803L25.3475 6.11699L24.9035 53.8886C24.8877 55.5827 26.1632 56.9233 27.7357 56.9054Z' fill='%23000'/> <path d='M83.5174 0.023629L67.0977 0.202892C65.9189 0.215762 64.9469 1.47413 64.932 3.01666C64.917 4.55918 65.8649 5.79659 67.0437 5.78372L83.4634 5.60446C84.6423 5.59159 85.6143 4.33322 85.6292 2.79069C85.6441 1.24817 84.6962 0.0107588 83.5174 0.023629Z' fill='%23000'/> <path d='M112.322 0.0234917L95.9026 0.202755C94.7238 0.215625 93.7518 1.47399 93.7369 3.01652C93.722 4.55905 94.6698 5.79645 95.8487 5.78358L112.268 5.60432C113.447 5.59145 114.419 4.33308 114.434 2.79056C114.449 1.24803 113.501 0.0106216 112.322 0.0234917Z' fill='%23000'/> <path d='M141.09 5.60418C142.269 5.59131 143.241 4.33295 143.256 2.79042C143.271 1.24789 142.323 0.0104842 141.144 0.0233544L124.724 0.202617C123.545 0.215487 122.573 1.47386 122.558 3.01638C122.544 4.55891 123.491 5.79632 124.67 5.78345L141.09 5.60418Z' fill='%23000'/> <path d='M153.529 0.202755C152.35 0.215625 151.378 1.47399 151.363 3.01652C151.349 4.55905 152.296 5.79645 153.475 5.78358L169.895 5.60432C171.074 5.59145 172.046 4.33308 172.061 2.79056C172.076 1.24803 171.128 0.0106214 169.949 0.0234916L153.529 0.202755Z' fill='%23000'/> <path d='M47.4551 20.9211L51.9544 20.8695L51.8267 34.7171L53.993 34.6923L54.1207 20.8447L58.6533 20.7928L58.6739 18.5565L47.4757 18.6847L47.4551 20.9211Z' fill='%23000'/> <path d='M65.4632 27.8386L72.4463 27.7587L72.3827 34.664L74.5493 34.6392L74.6976 18.5566L72.531 18.5814L72.4665 25.5762L65.4833 25.6561L65.5479 18.6613L63.3813 18.6861L63.2329 34.7687L65.3995 34.7439L65.4632 27.8386Z' fill='%23000'/> <path d='M86.482 26.527L83.319 26.5632L83.371 20.9066L86.8837 20.8663C88.5818 20.8469 89.1842 22.3076 89.1717 23.6681C89.1599 24.9569 88.6796 26.5017 86.4987 26.5268M83.2819 28.7831L85.0299 28.7631L88.854 34.6795L91.501 34.6492L87.5943 28.662C90.295 28.2194 91.3158 25.8272 91.3361 23.6254C91.3587 21.173 90.2009 18.5551 86.888 18.5931L81.2278 18.658L81.0796 34.7508L83.2438 34.7259L83.2987 28.765L83.2819 28.7831Z' fill='%23000'/> <path d='M105.993 32.4244L99.0312 32.5045L99.0729 27.9535L104.938 27.8861L104.959 25.6464L99.0935 25.7139L99.1379 20.8763L105.867 20.7989L105.887 18.5593L97.0151 18.6614L96.8673 34.7687L105.972 34.664L105.993 32.4244Z' fill='%23000'/> <path d='M118.843 28.4684L114.417 28.5189L116.68 22.2417L118.826 28.4686L118.843 28.4684ZM120.99 34.6417L123.294 34.6155L117.732 18.6217L115.728 18.6446L109.851 34.7687L112.172 34.7423L113.629 30.6891L119.624 30.6207L121.007 34.6416L120.99 34.6417Z' fill='%23000'/> <path d='M133.476 32.4683L129.872 32.5095L129.979 20.9092L133.584 20.868C136.37 20.8362 138.135 23.1037 138.102 26.6427C138.069 30.1818 136.247 32.4188 133.477 32.4504M140.288 26.6178C140.333 21.7918 137.643 18.5697 133.604 18.6159L127.814 18.682L127.666 34.7508L133.456 34.6847C137.494 34.6386 140.244 31.3902 140.288 26.5999' fill='%23000'/> <path d='M47.4577 42.9768L51.9899 42.9249L51.8607 56.9341L53.9102 56.9107L54.0394 42.9014L58.5716 42.8495L58.5905 40.792L47.4766 40.9192L47.4577 42.9768Z' fill='%23000'/> <path d='M69.1876 55.0464C66.0448 55.0821 63.6628 52.397 63.6944 48.9884C63.726 45.5799 66.1753 42.8219 69.3013 42.7863C72.4274 42.7507 74.8593 45.471 74.8278 48.8617C74.7963 52.2524 72.3471 55.0104 69.1876 55.0464ZM69.3207 40.6983C65.0412 40.747 61.6972 44.4609 61.6548 49.0295C61.6124 53.598 64.8885 57.2009 69.168 57.1522C73.4475 57.1035 76.825 53.3892 76.8671 48.8564C76.9092 44.3236 73.6002 40.6497 69.3207 40.6983Z' fill='%23000'/> <path d='M89.514 50.737L93.792 50.6883C93.6337 53.3498 91.6629 55.0501 88.9558 55.081C85.8141 55.1167 83.4332 52.3949 83.4647 49.003C83.4961 45.6111 85.9449 42.8164 89.0698 42.7808C90.4568 42.7651 91.7216 43.3218 92.6656 44.2215L94.1329 42.7589C92.8415 41.4705 91.0611 40.6697 89.0725 40.6923C84.8112 40.7408 81.4516 44.4562 81.4092 49.0264C81.3668 53.5965 84.6418 57.2007 88.9199 57.152C93.1979 57.1033 96.0467 54.4112 96.0988 48.7877L89.5147 48.8627L89.4972 50.755L89.514 50.737Z' fill='%23000'/> <path d='M102.943 50.0825L108.891 50.0141L108.909 47.9715L102.962 48.0399L103.009 42.8976L109.82 42.8192L109.839 40.7946L101 40.8963L100.853 56.9862L109.907 56.882L109.926 54.8573L102.898 54.9382L102.943 50.0825Z' fill='%23000'/> <path d='M114.134 42.9766L118.683 42.9245L118.554 56.9338L120.586 56.9105L120.715 42.9012L125.248 42.8493L125.267 40.7918L114.153 40.919L114.134 42.9766Z' fill='%23000'/> <path d='M139.327 47.8995L132.094 47.9823L132.159 40.898L130.143 40.9211L129.995 56.9859L132.011 56.9628L132.076 49.968L139.309 49.8852L139.244 56.88L141.294 56.8565L141.442 40.7918L139.392 40.8152L139.327 47.8995Z' fill='%23000'/> <path d='M149.628 50.0826L155.575 50.0142L155.594 47.9716L149.646 48.04L149.694 42.8977L156.505 42.8193L156.524 40.7946L147.702 40.8961L147.554 56.986L156.609 56.8819L156.627 54.8572L149.583 54.9382L149.628 50.0826Z' fill='%23000'/> <path d='M163.809 48.9066L163.865 42.9093L167.51 42.8675C169.241 42.8476 169.909 44.3794 169.896 45.8474C169.882 47.3154 169.202 48.8447 167.371 48.8657L163.809 48.9066ZM168.019 50.8273C170.818 50.5446 171.954 48.2224 171.976 45.8414C171.999 43.3172 170.741 40.8077 167.595 40.8437L161.852 40.9096L161.705 56.9859L163.752 56.9624L163.807 50.9472L165.721 50.9253L169.528 56.8961L171.974 56.8681L168.036 50.8271L168.019 50.8273Z' fill='%23000'/> </svg>");
  display: inline-block; width: 112px; height: 38px;
  background: currentColor; vertical-align: middle;
  -webkit-mask: var(--logo) no-repeat center / contain;
          mask: var(--logo) no-repeat center / contain;
}
.logo-mark.lg { width: 168px; height: 56px; }
@media (max-width: 480px) { .logo-mark { width: 96px; height: 32px; } }

/* The notch is painted by giving the label the surface colour behind it, so it
   has to know which surface it is sitting on. Anywhere a field appears on
   something other than the page background, the label follows. */
dialog .field:has(> input, > select, > textarea) > label { background: var(--md-surface-container-high); }
.auth-card .field:has(> input, > select, > textarea) > label { background: var(--md-surface); }
.run-head .field:has(> input, > select, > textarea) > label,
.filters-row .field:has(> input, > select, > textarea) > label { background: var(--md-surface-container-low); }
.appcard .field:has(> input, > select, > textarea) > label { background: var(--md-surface); }

/* A checkbox inside a field is a choice, not a text input — it gets no notch. */

