/* Nautelia: the single stylesheet. Tokens from the prototype, defined ONCE here
   (skill nautelia-ui-ux). Only use tokens that exist: lib/__tests__/styles.test.js
   fails on an undefined var(--x). Bump ?v= in the pages when this file changes. */

:root {
  --bg: #0B0F19;
  --panel: #131A2A;
  --panel-2: #1A2336;
  --activity: #9AA6BD;   /* an activity's colour, set per element from the API (safeColor); neutral here */
  --side: #0E1320;      /* the shell's side bar and tab bar (Claude Design, 28-sep) */
  --line: rgba(255, 255, 255, 0.10);
  --text: #F4F4F2;
  --text-dim: #9AA6BD;
  --orange: #FF4B12;
  --blue: #2979FF;
  --green: #28A96B;
  --amber: #E0A33E;
  --red: #E5484D;   /* a red, far from the brand orange (Estela, 2-oct: orange only for buttons and titles) */
  --ink: #0A0A0A;
  --radius: 8px;
  --tap: 48px;
  --tap-secondary: 44px;
  --font-body: 'DM Sans', system-ui, sans-serif;
  --font-display: 'Barlow', 'DM Sans', system-ui, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, monospace;
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background-color: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

.wrap { max-width: 740px; margin: 0 auto; padding: 0 16px 80px; }
h1, h2 { font-family: var(--font-display); font-weight: 900; text-transform: uppercase; margin: 0; }
h1 { font-size: 26px; }
h2 { font-size: 15px; letter-spacing: 0.04em; }
.meta { font-size: 14px; color: var(--text-dim); margin: 4px 0 0; }
.mono { font-family: var(--font-mono); }
[hidden] { display: none !important; }

/* Brand */
.brand { display: flex; align-items: center; gap: 10px; padding: 16px 0 12px; }
.brand__word { font-family: var(--font-display); font-weight: 900; font-size: 26px; line-height: 0.85; letter-spacing: -0.025em; }
.brand__word span { color: var(--orange); }

/* Buttons: same base per level, only the colour changes */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; min-height: var(--tap); padding: 12px 16px;
  border: 1px solid transparent; border-radius: var(--radius);
  background-color: var(--orange); color: var(--ink);
  font-family: var(--font-body); font-size: 15px; font-weight: 700; cursor: pointer; text-decoration: none;
}
.btn--secondary {
  min-height: var(--tap-secondary); font-size: 14px;
  background-color: transparent; color: var(--text); border-color: var(--line);
}
.btn--danger { background-color: transparent; color: var(--red); border-color: var(--red); }
.btn[disabled] { opacity: 0.45; cursor: not-allowed; }
/* On its way: a pressed button keeps its own words or icon and its colour, only dimmed, until the
   action ends (Estela, 30-sep: the busy words laid over it looked blurred; one look for every button). */
.btn.is-busy, .btn.is-busy[disabled] { opacity: 0.5; cursor: progress; }
.field.is-busy { opacity: 0.6; cursor: progress; }
.actions { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; }

/* Chips (filters, person selector) */
.chips { position: relative; display: flex; gap: 8px; overflow-x: auto; padding: 12px 0 4px; }   /* relative: its chips' offsetLeft is within it */
.chip {
  flex: none; display: inline-flex; align-items: center; gap: 8px;
  min-height: var(--tap-secondary); min-width: var(--tap-secondary); justify-content: center; padding: 10px 14px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background-color: transparent; color: var(--text-dim);
  font-family: var(--font-body); font-size: 14px; cursor: pointer; text-decoration: none;
}
/* "Volver": a small link, not a box (Estela, 29-sep) */
.chip.back { border: none; background: transparent; background-color: transparent; padding: 4px 0; min-height: 0; font-size: 14px; color: var(--text-dim); }
.chip.back::before { content: "‹ "; }
.chip[aria-pressed="true"] { color: var(--text); border-color: var(--blue); }
.chip__dot { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }

/* Session card */
.day { margin-top: 20px; }
.day__head { font-family: var(--font-display); font-weight: 900; font-size: 15px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--orange); padding-bottom: 8px; border-bottom: 1px solid var(--line); }
.card {
  display: block; margin-top: 10px; padding: 14px 16px; min-height: var(--tap);
  background-color: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--text); text-decoration: none;
}
/* "Finalizada": a past day's session, shown like the rest with this tag (Estela, 30-sep) */
.hero__meta { margin-top: 8px; }   /* the level under the activity (Estela, 30-sep) */
/* "Tienes plaza" top right (Estela, 30-sep): over the seats and over the buttons; not in the detail,
   where being in the list says it. */
.hero__side { flex: none; }
.card__side, .hero__side, .booking__side { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; text-align: right; }
.card__side > .state, .booking__tags > .state { margin-top: 0; }
.booking__tags { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }   /* "Tienes plaza", then "Finalizada" under it (Estela, 30-sep) */
/* A one-off session (Estela, 1-oct): "Puntual · Regata", a square blue label (not the prototype's amber). */
.tag-one-off, .tag-partner { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 4px; font-size: 13px; color: var(--blue); background-color: rgba(41, 121, 255, 0.14); border: 1px solid; border-color: var(--blue); }   /* "Puntual" and "Socio" (2-oct: blue; the orange is for buttons and titles) */
.tag-own { display: inline-flex; align-items: center; margin-top: 4px; padding: 2px 8px; border-radius: 4px; font-size: 13px; color: var(--green); background-color: rgba(40, 169, 107, 0.14); border: 1px solid; border-color: var(--green); }   /* the logbook's own sessions (1-oct) */
.card__when, .card__title { display: flex; flex-wrap: wrap; align-items: center; column-gap: 10px; row-gap: 4px; }   /* "Sábado 3 oct  10:00", then "REMO  [Puntual · Regata]" (Estela, 1-oct) */
.tag-finished { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: var(--radius);
  border: 1px solid var(--text-dim); background-color: var(--text-dim); color: var(--bg);   /* solid, it must be seen (30-sep) */
  font-family: var(--font-display); font-weight: 900; font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; }
.tag-cancelled { border-color: var(--red); background-color: var(--red); color: #fff; }   /* solid red, it must be seen (1-oct) */
.card { position: relative; }
.card::after { content: "›"; position: absolute; top: 10px; right: 14px; color: var(--text-dim); font-size: 18px; }   /* like the prototype (30-sep) */
.card__top { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; padding-right: 18px; }
.card__meta { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 8px; font-size: 13px; color: var(--text-dim); }
.card__meta b { color: var(--text); font-weight: 600; }
.card__time { font-family: var(--font-display); font-weight: 900; font-size: 22px; }
.card__activity { font-size: 14px; text-transform: uppercase; letter-spacing: 0.05em; }
.bar { height: 7px; margin-top: 10px; border-radius: 4px; overflow: hidden; display: flex; background-color: var(--line); }   /* translucent: seen on any card */
.bar__full { background-color: var(--blue); }
.bar__pending { background-color: var(--amber); }

/* Tones: one map (lib/copy.js bookingStates), four tones */
.tone-ok { color: var(--green); }
.tone-warn { color: var(--amber); }
.tone-risk { color: var(--red); }
.tone-info { color: var(--blue); }
.state { font-weight: 700; font-size: 15px; margin-top: 8px; }
/* The day's forecast: its activities as pills in THEIR colour (--activity, from the
   API through safeColor). The risk is one tag for the whole day (Estela, 28-sep). */
.pill { display: inline-flex; align-items: center; padding: 6px 14px; border-radius: 20px;
  color: var(--activity); background-color: color-mix(in srgb, var(--activity) 16%, transparent); font-size: 15px; }
/* A state as a tinted pill, after the plain one so it wins (Estela, 1-oct, the prototype's licence states): green, amber, red. */
.pill--ok { color: var(--green); background-color: rgba(40, 169, 107, 0.14); border: 1px solid; border-color: var(--green); }
.pill--warn { color: var(--amber); background-color: rgba(224, 163, 62, 0.14); border: 1px solid; border-color: var(--amber); }
.pill--risk { color: var(--red); background-color: rgba(229, 72, 77, 0.14); border: 1px solid; border-color: var(--red); }
.licences .pill { white-space: nowrap; margin-left: auto; }   /* on the name's line, pulled right (Estela, 1-oct) */
.licences .row > div:first-child { flex-grow: 1; min-width: 0; }

/* Blocks, lists, notices */
.block { margin-top: 14px; padding: 14px 16px; background-color: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); }
.row { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 10px 0; border-top: 1px solid var(--line); }
.row:first-child { border-top: none; }
.notice { display: flex; gap: 10px; padding: 12px 0; border-top: 1px solid var(--line); }
.notice:first-child { border-top: none; }
.notice--unread strong { color: var(--text); }
/* Unread (Estela, 29-sep): a small orange dot before it and the text bright; read ones stay grey.
   (An orange edge first: "sale un poco feo".) */
.notice { align-items: baseline; }
.notice--unread::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background-color: var(--orange); transform: translateY(-1px); }
.notice--unread .meta { color: var(--text); }
.page-head__action { margin-left: auto; }   /* a page's own button on its title's line (Avisos) */
.page-head__action .btn { width: auto; }
/* A count on a nav link and beside its title (the unread notices) */
.badge { display: inline-flex; align-items: center; justify-content: center; min-width: 22px; height: 22px; padding: 0 7px;
  margin-left: 8px; border-radius: 11px; background-color: var(--orange); color: var(--ink); font-size: 13px; font-weight: 700; line-height: 1; }
.field { width: 100%; min-height: var(--tap); padding: 12px; border: 1px solid var(--line); border-radius: var(--radius); background-color: var(--panel-2); color: var(--text); font-family: var(--font-body); font-size: 16px; }

/* The route map: SVG at once, OpenFreeMap's dark style when MapLibre loads (phase 5; 2-oct). The credit, ours,
   always visible over the map's corner. */
.map { position: relative; margin-top: 10px; height: 220px; border-radius: var(--radius); overflow: hidden; background-color: var(--panel-2); }
.map .route { width: 100%; height: 100%; display: block; }
.map__attribution { position: absolute; right: 0; bottom: 0; z-index: 2; padding: 2px 6px; border-top-left-radius: 4px;
  background-color: rgba(11, 15, 25, 0.75); color: var(--text-dim); font-size: 11px; line-height: 1.4; }
.map__attribution a { color: var(--text-dim); }

/* Logbook: the numbers and the bars (phase 5) */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); gap: 10px; margin-top: 14px; }
.stat { display: flex; flex-direction: column; padding: 12px; background-color: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); }
.stat strong { font-family: var(--font-display); font-size: 22px; }
.stat--link { color: inherit; text-decoration: none; border-color: var(--amber); }   /* "Cosas que mirar": to Por resolver (Estela, 1-oct) */
.stat--link .meta { color: var(--amber); }
.stat--risk { border-color: var(--red); }   /* to "En riesgo de no salir", red like its table (Estela, 1-oct) */
.stat--risk .meta { color: var(--red); }
/* The logbook like the prototype (Estela, 1-oct): km per session as rows (date, bar, km); a small route drawing */
.kmbars__row { display: flex; align-items: center; column-gap: 10px; padding: 4px 0; }
.kmbars__day { width: 52px; flex: none; font-size: 13px; color: var(--text-dim); }
.kmbars__track { flex-grow: 1; height: 10px; border-radius: 4px; overflow: hidden; background-color: var(--panel-2); }
.kmbars__track i { display: block; height: 100%; background-color: var(--blue); }
.kmbars__km { width: 42px; flex: none; text-align: right; font-size: 13px; }
.route--thumb { display: block; flex: none; width: 140px; height: auto; border-radius: 8px; background-color: var(--panel-2); }   /* on the right of its row, small (1-oct) */
/* Your sessions: one column on a phone, two on a desktop (Estela, 2-oct); a line between cells */
.logbook__rows { display: grid; grid-template-columns: minmax(0, 1fr); column-gap: 32px; }
.logbook__cell { border-top: 1px solid var(--line); }
.logbook__cell:first-child { border-top: none; }
.logbook__cell .row { border-top: none; }
@media (min-width: 900px) {
  .logbook__rows { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .logbook__cell:nth-child(2) { border-top: none; }
}
.logbook__more { display: flex; justify-content: center; margin-top: 14px; }   /* out of the block, centred (1-oct) */

/* A line-up row: name, seat selector (takes the room left), save */
.seat { flex-wrap: wrap; }
.seat select { flex: 1 1 9rem; min-width: 0; width: auto; }

/* Toast: role="status", written to AFTER it is shown */
.toast {
  position: fixed; left: 50%; transform: translateX(-50%);
  top: calc(16px + env(safe-area-inset-top, 0px)); width: min(92vw, 460px);   /* at the top (Estela, 29-sep) */
  padding: 14px 16px; background-color: var(--panel-2); border: 1px solid var(--blue); border-radius: var(--radius);
  font-size: 15px; z-index: 50;
}

/* Day cards (plan responsive, step 2): one per day, scroll sideways on mobile */
.daycards { position: relative; display: flex; gap: 8px; overflow-x: auto; padding: 2px 0 6px; flex: 0 1 auto; min-width: 0; }   /* › right after Sunday */
/* The seven days, "MIÉ 30 SEP" and nothing else, square like the filters (Estela, 30-sep); a 44 px tap target. */
.daycard { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; min-height: var(--tap);
  padding: 0 14px; border: 1px solid var(--line); border-radius: var(--radius); background-color: var(--panel);
  color: var(--text); font-family: var(--font-body); cursor: pointer; }
.daycard[aria-pressed="true"] { border-color: var(--blue); background-color: var(--panel-2); }
.daycard__day { font-family: var(--font-display); font-weight: 900; font-size: 13px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-dim); }
.daycard__date { display: flex; align-items: baseline; gap: 6px; }   /* "MIÉ 30 SEP" on one line */
.daycard__day--today { color: var(--orange); }
.daycard__num { font-family: var(--font-display); font-weight: 900; font-size: 15px; line-height: 1; }
.daycard__month { font-family: var(--font-display); font-weight: 900; font-size: 13px; text-transform: uppercase; color: var(--text-dim); }
/* A phone (Estela, 30-sep): the seven days fit, each a seventh, "MIÉ" over "30"; the month is in
   the day's title below. From 600 px, "MIÉ 30 SEP" on one line, as before. */
.weeknav .daycards { flex: 1 1 auto; justify-content: center; gap: 4px; overflow-x: visible; }
.weeknav .daycard { flex: 1 1 0px; min-width: 0; max-width: 44px; padding: 4px 0; }   /* narrow (Estela, 30-sep) */
.weeknav .daycard__date { flex-direction: column; align-items: center; gap: 2px; }
.weeknav .daycard__month { display: none; }
.weeknav .daycard__day { font-size: 11px; letter-spacing: 0.02em; }
.weeknav .weeknav__arrow { min-width: 32px; padding-left: 0; padding-right: 0; }   /* no wider than a day on a phone */
@media (min-width: 600px) {
  .weeknav .daycards { flex: 0 1 auto; gap: 6px; overflow-x: auto; }
  .weeknav .daycard { flex: 0 0 auto; max-width: none; padding: 0 10px; }   /* narrower (Estela, 30-sep: "fechas más estrechas") */
  .weeknav .daycard__date { flex-direction: row; align-items: baseline; gap: 6px; }
  .weeknav .daycard__month { display: inline; }
  .weeknav .daycard__day { font-size: 13px; letter-spacing: 0.06em; }
  .weeknav .weeknav__arrow { min-width: var(--tap-secondary); padding-left: 14px; padding-right: 14px; }
}
.weather--line .state { font-size: 13px; white-space: nowrap; }   /* "No recomendado" on one line (Estela, 29-sep) */

/* ==== The responsive shell (Claude Design handoff, 28-sep; plan responsive, step 1) ====
   Mobile first: a header with the brand and "Salir", and the nav in a tab bar
   fixed at the bottom. From 900 px: a 280 px side bar with the nav and the user
   card. Both navs are painted by app/main.js from the table's ONE nav(). */
.shell { min-height: 100vh; }
.shell > main { padding: 16px 16px calc(96px + env(safe-area-inset-bottom, 0px)); min-width: 0; }
.side { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 16px 12px; border-bottom: 1px solid var(--line); background-color: var(--side); }
.side .brand { padding: 0; }
.side__nav, .side__user { display: none; }
.side__logout-mobile { width: auto; min-height: var(--tap-secondary); padding: 8px 14px; }

.tabbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; display: flex;
  background-color: var(--side); border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom, 0px); }
.tabbar a { flex: 1 1 0; min-width: 0; min-height: 60px; display: flex; align-items: center; justify-content: center;
  padding: 6px 4px; border-top: 3px solid transparent; color: var(--text-dim); font-size: 14px; text-decoration: none; }
.tabbar a[aria-current="page"] { color: var(--text); font-weight: 700; border-top-color: var(--orange); }
/* "Más" (Estela, 1-oct: dirección's 7 tabs did not fit): a tab like the others, its sheet above the bar */
.tabbar__more { flex-grow: 1; flex-shrink: 1; flex-basis: 0; min-width: 0; min-height: 60px; display: flex; align-items: center; justify-content: center; gap: 4px;
  padding: 6px 4px; border: none; border-top: 3px solid transparent; background-color: transparent; color: var(--text-dim);
  font: inherit; font-size: 14px; cursor: pointer; }
.tabbar__more[aria-current="page"], .tabbar__more[aria-expanded="true"] { color: var(--text); font-weight: 700; border-top-color: var(--orange); }
.tabbar__sheet { position: fixed; left: 0; right: 0; bottom: calc(63px + env(safe-area-inset-bottom, 0px)); z-index: 41;
  display: flex; flex-direction: column; background-color: var(--side); border-top: 1px solid var(--line); box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.4); }
.tabbar__sheet a { min-height: 52px; display: flex; align-items: center; justify-content: space-between; padding: 0 20px;
  border-bottom: 1px solid var(--line); color: var(--text); text-decoration: none; }
.tabbar__sheet a[aria-current="page"] { color: var(--orange); font-weight: 700; }

/* The page head: role tag + section title, and its line */
.page-head { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.page-head__row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.role-tag { padding: 5px 10px; border: 1px solid var(--line); border-radius: var(--radius);
  background-color: var(--panel-2); font-family: var(--font-display); font-weight: 900;
  font-size: 15px; letter-spacing: 0.08em; text-transform: uppercase; }
.page-head .meta { font-size: 15px; margin: 0; }
.page-head .page-head__section { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; font-size: 18px; font-weight: 600; color: var(--orange); }   /* staff: the menu section under "Panel de dirección" (Estela, 1-oct) */
.page-head__section .badge { margin-left: 0; }   /* the line's gap spaces it */

@media (min-width: 900px) {
  .shell { display: grid; grid-template-columns: 280px minmax(0, 1fr); }
  .side { position: sticky; top: 0; height: 100vh; overflow-y: auto; flex-direction: column; align-items: stretch;
    justify-content: flex-start; gap: 22px; padding: 24px 16px; border-bottom: none; border-right: 1px solid var(--line); }
  .side__logout-mobile, .tabbar, .tabbar__sheet { display: none; }
  .side__nav { display: flex; flex-direction: column; gap: 2px; }
  .side__nav a { display: flex; align-items: center; gap: 10px; min-height: var(--tap-secondary);
    padding: 10px 14px; border-radius: var(--radius); color: var(--text-dim); font-size: 15px; text-decoration: none; }
  .side__nav a[aria-current="page"] { background-color: var(--panel-2); color: var(--text); }
  .side__user { display: flex; flex-direction: column; gap: 10px; margin-top: auto; padding: 14px;
    background-color: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); }
  .side__who { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; }   /* name and role, one line (Estela, 30-sep) */
  .shell > main { padding: 28px 36px 60px; }
  .page-head h1 { font-size: 34px; }
}

/* List + detail at once (plan responsive, step 3): the detail route paints both;
   under 1180 px the detail replaces the list, with its back link. */
.split__list { display: none; }
.split--pick .split__list { display: block; }
.split--pick .split__detail { display: none; }
.wide-only { display: none; }   /* the calendar above a session detail: only beside it, from 1180 px */
.card[aria-current="true"] { border-color: var(--blue); background-color: var(--panel-2); }
@media (min-width: 1180px) {
  .split { display: flex; gap: 28px; align-items: flex-start; }
  .split__list { display: block; flex: 0 1 460px; min-width: 0; }
  .split__detail { flex: 1 1 0; min-width: 0;   /* its own height, no scroll of its own: the page scrolls (Estela, 28-sep) */
    padding: 20px 22px; background-color: var(--side); border: 1px solid var(--line); border-radius: 12px; }
  .split__detail .back { display: none; }
  .split__list > .day:first-child, .split__list > .day:first-child > .card:first-child { margin-top: 0; }   /* list and detail start level */
  .split--pick .split__detail { display: block; }
  .wide-only { display: block; }
}

/* Attendance: Está / Falta, three states (plan responsive, step 4). The pressed
   one is what the API has; neither pressed is "not marked yet". */
.block__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
/* A block's button in its head (Licencias, Estela 1-oct): a phone, under the title, centred; a wide
   screen, beside it, right. Only heads with a button: Apuntados keeps its "x de y" beside the title. */
.licences .block__head h2 { flex-basis: 100%; }
.block__head .btn { margin-left: auto; margin-right: auto; }
@media (min-width: 600px) {
  .licences .block__head h2 { flex-basis: auto; }
  .block__head .btn { margin-right: 0; }
}
.block__head + .row { border-top: none; }
/* Mis datos (Estela, 30-sep: "no es responsive"): on a phone the label over its value, the pills
   wrap; from 600 px, side by side as before. */
.profile .row { flex-direction: column; align-items: flex-start; gap: 4px; }
.profile .chips { flex-wrap: wrap; overflow-x: visible; padding: 4px 0; }
.profile .plans { display: flex; flex-direction: column; gap: 8px; }   /* one line per activity paid (Estela, 1-oct) */
.profile .plan { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
@media (min-width: 600px) {
  .profile .row { flex-direction: row; align-items: center; gap: 10px; }
  .profile .row > :last-child { text-align: right; }
  .profile .chips { justify-content: flex-end; }
  .profile .plans { align-items: flex-end; }
}
/* Mensajes (Estela, 29-sep): who and about what, the text, and the reply on one line */
.message { padding: 12px 0; border-top: 1px solid var(--line); }
.message:first-child { border-top: none; padding-top: 0; }
.message__text { margin: 8px 0 10px; }
.reply { display: flex; gap: 10px; align-items: stretch; }
.reply .field { flex: 1 1 auto; min-width: 0; margin: 0; }
.reply .btn { width: auto; flex: none; }
.person { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; min-width: 0; }   /* name and level on one line */
.person .meta { margin: 0; }
.person__extra { flex-basis: 100%; }   /* the guardian, below */   /* no line under the title (Estela, 29-sep) */
/* Inicio (Estela, 29-sep): one booking per row, what it is on the left, its action on the right. */
.bookings { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.bookings .card { margin-top: 0; }
/* Mis sesiones on a big screen: two per row (Estela, 30-sep); a phone keeps one column. */
@media (min-width: 1180px) { .bookings { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.bookings__item { display: flex; flex-direction: column; gap: 10px; }
.bookings__item > .card { flex: 1; }
/* An Inicio row (Estela, 29-sep): the date and its state on one line; the activity with the
   button on its right (no hole under it); then the sea. The link's rows sit in the card's grid. */
.booking { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 12px; row-gap: 6px; align-items: center; }
.booking__main { display: contents; color: inherit; text-decoration: none; }
.booking__main > * { grid-column: 1; }   /* the right column is the state and the buttons (30-sep) */
.booking .card__meta { flex-direction: column; gap: 2px; }   /* a phone: one fact per line, every card alike */
@media (min-width: 600px) { .booking .card__meta { flex-direction: row; gap: 4px 14px; } }
.booking__main > .booking__title { grid-column: 1; grid-row: 2; }
.booking__when { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; min-width: 0; }   /* "Finalizada" drops a line on a phone, never under the state (Estela, 30-sep) */
.booking__when .eyebrow { white-space: nowrap; }
.booking__title { display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px; }
.booking__info { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 14px; }
.booking__main .state, .booking__main .weather { margin-top: 0; }
.booking__side { grid-column-start: 2; grid-row-start: 1; grid-row-end: span 3; align-self: stretch; justify-content: space-between; }   /* state on top, buttons on the last line (Estela, 30-sep) */   /* longhands: jsdom reads no grid shorthand */
.booking__actions { display: flex; gap: 8px; }
.card.booking::after { content: none; }   /* "Ver" is its own button (Estela, 30-sep) */
.booking .weather--line .meta { font-size: 13px; }   /* a phone: "Se sale" beside the gusts (Estela, 29-sep) */
/* A phone (Estela, 29-sep): the button is its icon; its words stay for screen readers (visually
   hidden, never display: none). The level keeps its word ("así no se entera una"). */
.booking .btn__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.booking .btn__icon { display: block; }
.booking .booking__actions .btn { min-width: 44px; min-height: 44px; padding: 0; justify-content: center; }
@media (min-width: 600px) {
  .booking .weather--line .meta { font-size: 14px; }
  .booking .btn__label { position: static; width: auto; height: auto; overflow: visible; clip: auto; }
  .booking .btn__icon { display: none; }
  .booking .booking__actions .btn { min-width: 0; padding: 8px 16px; }
}
.attend { display: flex; gap: 8px; }
/* A past day: not dimmed, the same as any other; its "Finalizada" tag says it (Estela, 3-oct; it was muted, 29-sep). */
.attend .btn { width: auto; min-width: 64px; }
.attend .btn[aria-pressed="true"][data-value="true"] { border-color: var(--green); color: var(--text); }
.attend .btn[aria-pressed="true"][data-value="false"] { border-color: var(--red); color: var(--text); }

/* Cards that fit the width by themselves: one column on a phone, three on a wide screen */

/* The week navigator: ‹ 28 sep – 4 oct › (Estela, 28-sep) */
.daycard--empty { opacity: 0.45; cursor: default; }   /* a day with nothing: there, but off (Estela, 30-sep) */
.weeknav { display: flex; align-items: center; gap: 4px; margin-top: 8px; }   /* ‹ the seven days › (Estela, 30-sep) */
@media (min-width: 600px) { .weeknav { gap: 8px; } }
.weeknav .daycards { margin: 0; }
.weeknav__arrow { flex: none; }
/* A week not open yet: when it opens, under the navigator (Estela, 30-sep) */
.week-closed { margin: 6px 0 0; color: var(--amber); }
/* The week's chosen classes used: a notice that shows, next to the disabled button (Estela, 30-sep) */
.weekly-full { margin: 0; padding: 10px 14px; border-left: 4px solid var(--amber); border-radius: 8px; background-color: rgba(224, 163, 62, 0.12); color: var(--amber); font-weight: 600; }
.chip:disabled { opacity: 0.4; cursor: default; }

/* Parte del día (Estela, 1-oct, the prototype): the number big on top, the label in capitals, no block around. */
.stats--big { grid-template-columns: repeat(2, 1fr); gap: 10px; margin: 0 0 16px; }
.stats--big .stat { padding: 16px 18px; gap: 6px; }
.stats--big .stat strong { font-size: 30px; line-height: 1; }
.stats--big .stat .meta { text-transform: uppercase; letter-spacing: 0.06em; font-size: 13px; }
@media (min-width: 600px) { .stats--big { grid-template-columns: repeat(4, 1fr); } }
.stats--three { grid-template-columns: repeat(3, 1fr); }   /* Licencias: its three in one line, a phone too (Estela, 1-oct) */
.stats--three .stat { padding: 14px 12px; }
.stats--three .stat .meta { font-size: 12px; letter-spacing: 0.03em; }
/* Parte del día: the day's cards two per row on a big screen, like Mis sesiones (Estela, 1-oct). */
.dayreport .day { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; margin-top: 0; }
.dayreport .day .card { margin-top: 0; }
@media (min-width: 1180px) { .dayreport .day { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Previsión (Estela, 1-oct, the prototype): the sea in a blue-edged block, one day per row; dirección's
   weather report in a red-edged one. */
.forecast__sea { border-left: 4px solid var(--blue); }
.forecast__report { border-left: 4px solid var(--red); }
.forecast > .block + .block { margin-top: 16px; }   /* the report on top, then the sea (Estela, 1-oct) */
.forecast__report h2 { color: var(--red); }
.forecast__day { padding: 14px 0; border-top: 1px solid var(--line); }
.forecast__day h3 { margin: 0 0 4px; font-size: 16px; }
.forecast__day h3::first-letter { text-transform: uppercase; }   /* "Jueves 1 oct" (the prototype) */
.forecast__day .meta { margin: 0; }
.forecast__day .chips { flex-wrap: wrap; overflow-x: visible; padding: 10px 0 6px; }
.pill--none { color: var(--text-dim); background-color: var(--panel-2); }
/* Sesiones, the fixed schedules (Estela, 1-oct): the form on one line, the cards two per row on a big screen. */
.schedules__form { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 10px; }
.schedules__form .field { flex: 1 1 9rem; min-width: 0; }
.schedules__form .btn { flex: none; margin-left: auto; }   /* always right, also alone on its line (Estela, 1-oct) */
.schedules__create .btn { min-width: 10.5rem; justify-content: center; }   /* both "Crear" the same width (Estela, 1-oct) */
.forecast__report .schedules__form .field { flex-grow: 1; flex-basis: 9rem; max-width: 20rem; }   /* a day picker beside its button, never the whole block (Estela, 1-oct) */
.schedules__day { margin-top: 32px; }   /* room between the days (Estela, 1-oct) */
.schedules__day .day__head { margin-top: 0; margin-bottom: 14px; }
.schedules__cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; align-items: start; }   /* editing one never stretches its neighbour (1-oct) */
.schedules__cards .card { margin-top: 0; }
.schedule__main { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.schedule .confirm-inline { margin-top: 10px; }
.schedule__buttons { display: flex; gap: 8px; flex: none; }
/* Editing a schedule (Estela, 1-oct): under its card, its instructor and its fixed seats */
.schedule-edit { display: flex; flex-direction: column; row-gap: 10px; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.schedule-edit h3 { margin: 6px 0 0; font-size: 15px; }
.schedule-edit__label { display: flex; flex-direction: column; row-gap: 6px; font-size: 14px; color: var(--text-dim); }
.card.schedule::after { content: none; }   /* not a link: no "›" */
@media (min-width: 1180px) { .schedules__cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.btn--small { width: auto; min-height: var(--tap-secondary); padding: 8px 14px; font-size: 14px; }

/* The day's title above the list and the detail (Estela, 28-sep): room around it */
.chips + .day__head { margin-top: 18px; }
.day__head + .split, .wide-only + .split { margin-top: 14px; }

/* The group's level (Estela, 28-sep, option C): a neutral tag with one, two or
   three dots lit; no colour, so it competes with nothing (activities, sea, notices). */

/* "Con avisos": another kind of filter, amber, a little apart from the activities (Estela, 28-sep) */

/* The session hero (Estela, 28-sep): date · time, the activity and its status,
   level and seats; confirmed/capacity big on the right; a row of small buttons. */
.hero { padding: 4px 0 0; }
.hero__top { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; }
.hero__main { min-width: 0; }
.hero__when { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }   /* the date, then "Anulada: …" */
.hero__eyebrow, .eyebrow { font-family: var(--font-display); font-weight: 900; font-size: 14px; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--text); }
.hero__title { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; margin-top: 6px; }
.hero__title h1 { font-family: var(--font-body); font-weight: 500; }   /* small, like the activity on a card */
.hero__count { flex: none; display: flex; flex-direction: column; align-items: flex-end; padding-left: 18px;
  border-left: 1px solid var(--line); }
.hero__count strong { font-family: var(--font-display); font-weight: 900; font-size: 44px; line-height: 1; }
.hero__count strong span { font-size: 22px; color: var(--text-dim); }
.hero__count .meta { margin: 6px 0 0; font-family: var(--font-display); font-weight: 900; letter-spacing: 0.1em; text-transform: uppercase; }
.hero__actions { display: flex; justify-content: space-between; align-items: flex-start; flex-wrap: wrap; gap: 10px;
  margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line); }
.hero__actions-main, .hero__actions-danger { display: flex; flex-wrap: wrap; gap: 10px; }
.hero { margin-bottom: 16px; }   /* room before what follows (the sea, the notices) */

/* The card's second line: the activity on the left, the level on the right (Estela, 28-sep) */
.card__row { display: flex; justify-content: space-between; align-items: center; gap: 10px; }

/* Monitor responsable, like the prototype (Estela, 28-sep): a coloured left edge
   and title, amber with no monitor, green with one; the select saves on change. */
.assign { border-left: 4px solid var(--amber); }
.assign h2 { color: var(--amber); margin-bottom: 10px; }
.assign--set { border-left-color: var(--green); }
.assign--set h2 { color: var(--green); }

/* Apuntados (Estela, 28-sep): "Quitar" small and outlined in orange; "Meter a
   alguien" and its button on one line at the end of the block. */
.btn--outline { background-color: transparent; color: var(--orange); border-color: var(--orange); }
.row .actions { flex-direction: row; align-items: center; margin-top: 0; }
.add-find { position: relative; margin-top: 12px; }
.add-find .field { margin: 0; }
/* The matches as a dropdown under the field, only while typing (Estela, 29-sep) */
.add-results:empty { display: none; }
.add-results { position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 20; max-height: 360px; overflow-y: auto;
  padding: 4px 12px; background-color: var(--panel-2); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.45); }
.add-results .row { padding: 8px 0; }
.add-match { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }

/* The sea and the notices sit left of the hero's buttons, in their row (Estela, 28-sep) */
.hero__info { flex-grow: 1; flex-shrink: 1; flex-basis: 0; min-width: 0; }   /* takes what is left: the buttons never drop below (Estela, 29-sep) */
.hero__info .weather .meta:first-child { margin-top: 0; }
.hero__buttons { display: flex; flex-wrap: wrap; gap: 10px; margin-left: auto; }

/* The boat (Estela, 28-sep, like the prototype): babor on top, estribor below,
   row 1 at the bow (left); each taken seat in its side's colour. */
.boat { margin: 16px 0 8px; text-align: center; }
.boat__label { display: block; font-family: var(--font-mono); font-size: 14px; }
.boat__label--port { color: var(--orange); margin-bottom: 6px; }
.boat__label--starboard { color: var(--blue); margin-top: 6px; }
.boat__hull { position: relative; border: 2px solid var(--line); border-radius: 50%; padding: 22px 9% 22px 12%; }
.boat__bow { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); font-family: var(--font-mono); font-size: 14px; color: var(--text-dim); }
.boat__seats { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 44px 12px; }
.boat__seat { min-height: var(--tap-secondary); display: flex; align-items: center; justify-content: center; padding: 0 4px;
  border-radius: 6px; background-color: var(--panel-2); color: var(--text-dim); font-family: var(--font-mono); font-size: 14px;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.boat__seat--port { background-color: var(--orange); color: var(--ink); }
.boat__seat--starboard { background-color: var(--blue); color: var(--ink); }
.field--small { width: auto; min-height: var(--tap-secondary); }
/* The line-up's rows (Estela, 2-oct: three selects did not fit on a phone): when Fila, Lado and Rema a do not fit
   beside the name, they wrap under it and share the width; where they fit, beside it as before. Longhands: jsdom. */
.lineup .row { flex-wrap: wrap; }
.lineup .row .actions { flex-grow: 1; flex-shrink: 1; flex-basis: 18rem; min-width: 0; justify-content: flex-end; }
.lineup .row .actions select { flex-grow: 1; flex-shrink: 1; flex-basis: 0px; min-width: 0; }

/* A label-button (the GPX upload) that cannot be used yet: same place, dimmed (Estela, 28-sep) */
.is-disabled { opacity: 0.45; pointer-events: none; }

/* Por resolver (Estela, 28-sep, from the prototype): a coloured edge and title per kind */
.todo--warn { border-left: 4px solid var(--amber); }
.todo--warn h2 { color: var(--amber); }
.todo--risk { border-left: 4px solid var(--red); }
.todo--risk h2 { color: var(--red); }
.todo--ok { border-left: 4px solid var(--green); }   /* nothing to do there (Estela, 1-oct) */
.todo--ok h2 { color: var(--green); }
.todo .row { flex-direction: column; align-items: stretch; }   /* a phone: the text full width, the buttons in one line under it (Estela, 1-oct) */
@media (min-width: 600px) { .todo .row { flex-direction: row; align-items: center; } }
.todo .row .actions { flex-wrap: wrap; justify-content: flex-end; }
.todo .row .actions .field { flex-grow: 1; flex-basis: 8rem; min-width: 0; width: auto; }   /* Licencias: the number beside "Tramitada" */
.todo__why { flex-basis: 100%; text-align: right; font-size: 13px; }   /* why "Invitar" is off, under the buttons (Estela, 1-oct) */

/* Compact confirmation (Estela, 28-sep): the question and small Sí / No on one line */
.confirm-inline { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px 16px;
  margin-top: 12px; padding: 10px 14px; border: 1px solid var(--red); border-radius: var(--radius); background-color: var(--panel-2); }
.confirm-inline .meta { margin: 0; color: var(--text); }
.confirm-inline__buttons { display: flex; gap: 8px; margin-left: auto; }
.confirm-inline--note .meta { flex: 1 1 100%; }   /* with a note: the sentence, then the note and Sí / No below */
.confirm-inline__note { flex: 1 1 220px; width: auto; min-width: 0; margin: 0; padding: 8px 12px; }
.row .confirm-inline { margin-top: 0; }
.hero__confirm { margin-top: 12px; }
/* The verdict right after the sea line (Estela, 28-sep) */
.weather--line { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 8px; }
.weather--line .meta { margin: 0; }
.weather--line .state, .hero__when .state, .booking__when .state { margin-top: 0; }
.hero__when .state, .booking__when .state { font-size: 13px; }   /* beside the date, small like the sea's verdict (29-sep) */
/* The footer (Estela, 29-sep): the forecast's source, refresh and reach, small and apart */
.app-footer { margin-top: 40px; padding-top: 14px; border-top: 1px solid var(--line); font-size: 14px; color: var(--text-dim); }

/* Usuarios (Estela, 2-oct; "Personas" until the same day): the name opens the commitment (a button that reads as text); search and filters */
.people__tools { display: flex; flex-direction: column; align-items: stretch; row-gap: 10px; margin: 14px 0; }   /* the filters under the search (2-oct) */
.people__name { padding: 0; border: none; background-color: transparent; color: var(--text); font-family: inherit; font-size: inherit; text-align: left; cursor: pointer; }
.people__row + .people__row { border-top: 1px solid var(--line); }
/* A row in two lines on a phone: the name and its licence, then the plan and the button (Estela, 2-oct: "en mobile
   organiza mejor"); on a wide screen the licence and the button sit on the right of both lines. */
.people__row { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 10px; row-gap: 6px; align-items: center; padding: 10px 0; }
.people__row > * { grid-column-start: 1; grid-column-end: -1; }   /* the question and the commitment: full width (longhands: jsdom does not expand the shorthand) */
.people__row > .people__name { grid-column-start: 1; grid-column-end: auto; grid-row-start: 1; justify-self: start; }
.people__row > .meta { grid-column-start: 1; grid-column-end: auto; grid-row-start: 2; min-width: 0; }
.people__row > .people__licence { grid-column-start: 2; grid-column-end: auto; grid-row-start: 1; justify-self: end; white-space: nowrap; }
.people__row > .people__partner { grid-column-start: 2; grid-column-end: auto; grid-row-start: 2; justify-self: end; white-space: nowrap; }
@media (min-width: 600px) {
  .people__row { grid-template-columns: minmax(0, 1fr) auto auto; }
  .people__row > .people__licence { grid-row-start: 1; grid-row-end: span 2; }
  .people__row > .people__partner { grid-column-start: 3; grid-row-start: 1; grid-row-end: span 2; }
}
.people__commitment { padding: 0 0 12px; }
.people__commitment p { margin: 4px 0; }
