/* web/css/base.css — Transversal (D219): theme and variables, reset, type, the bar and the tabs,
   the foot, sheets, dialogs, buttons, tables, notices, empty states and every rule more than one
   team uses. Loaded first; en-viaje.css, planificar.css and cuenta-y-acceso.css follow, in that
   order. Changing it asks the dev manager's OK (docs/specs/equipos/02-como-trabajan.md).
   E31-2 moved here, as it was, index.html's <style>; then the rules of one team went to that
   team's file, and the ones listed in docs/specs/equipos/03-partir-index.md §6 stayed here
   because their order against a shared rule decides what is drawn. */
/* Layout: one rail-map sheet. Map left, a vertical line diagram right (thick rail = nights spent, thin rail = travel).
   Palette after the rail-diagram tradition: paper, sumi ink, one red. Status is encoded by fill/outline, not by extra hues. */
:root{
  --paper:#fafaf8; --ink:#16171a; --ink2:#5f6268; --ink3:#6b6d73; --hair:#dcdcd8; --land:#ececea; --landline:#b9bab6; --pref:#d6d6d2;
  --red:#c8102e; --redsoft:rgba(200,16,46,.09); --sakura:#e7a3b4; --white:#ffffff;
  --ida:#c8102e; --vuelta:#2b4c9b; --dtc:#2f8a5a;
  --mincho:"Zen Old Mincho","Hiragino Mincho ProN","Yu Mincho",serif;
  --gothic:"BIZ UDPGothic","Hiragino Sans","Yu Gothic",system-ui,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,Menlo,monospace;
}
/* D150 (1), P1: text greys and chips at >= 4.5:1. --ink3 is now #6b6d73 / #8a8c92 (was
   #9a9ca1 / #6c6e74, 2.63 and 3.58:1). The map also draws with it (sea names, rail
   network, optional routes): compared side by side it reads the same, so no separate
   text-only grey. --sakurat: the sakura as text ("misma época"); --dtct: the green as text
   ("le deben", "listo"); --redbg / --okbg: red and green behind white text (badges, pills). */
:root{--sakurat:#b4475f;--dtct:#24704a;--redbg:#c8102e;--okbg:#24704a}
:root[data-theme="dark"]{--sakurat:#d98aa0;--dtct:#5cc08a;--redbg:#d92b3d}
/* Round 4 of the interactive map (the human: hotels must stand out by colour): hotels are
   blue in every map, the route's "vuelta" blue, which red/green colour-blind eyes tell from
   the attractions' red and the day trips' green; never by colour alone (a pin with a bed,
   the attractions' numbered dots, the day trips' rings). --hotel draws lines and text,
   --hotelbg sits behind white (>= 4.5:1 in both themes), --hotelsoft is a faint fill. */
:root{--hotel:#2b4c9b;--hotelbg:#2b4c9b;--hotelsoft:rgba(43,76,155,.1)}
:root[data-theme="dark"]{--hotel:#86a2f2;--hotelbg:#3d63d6;--hotelsoft:rgba(134,162,242,.14)}
:root[data-theme="dark"]{
  --paper:#141518; --ink:#ecebe8; --ink2:#a3a5aa; --ink3:#8a8c92; --hair:#2c2e33; --land:#202227; --landline:#3d4047; --pref:#2a2c31;
  --red:#ff4d5e; --redsoft:rgba(255,77,94,.12); --sakura:#d98aa0; --white:#1b1c20; --ida:#ff4d5e; --vuelta:#86a2f2; --dtc:#5cc08a; color-scheme:dark}

*{box-sizing:border-box}
html,body{background:var(--paper)}
body{margin:0;color:var(--ink);font-family:var(--gothic);font-size:14px;line-height:1.55;
  padding-left:max(16px,env(safe-area-inset-left,0px));padding-right:max(16px,env(safe-area-inset-right,0px));padding-block:0 40px}
p{margin:0}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
:focus-visible{outline:2px solid var(--red);outline-offset:2px}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}
.kj{font-family:var(--mincho);font-weight:900}
/* The brand isotype (#wf-iso, 74 x 82): sized by font-size like the .kj text it replaced. Always
   the brand red #D71920, in both themes: it is a logo (3:1 for graphics holds on #141518), the
   UI and text reds stay --red. */
.wfi{display:inline-block;flex:none;width:.9em;height:1em;color:#d71920;vertical-align:-.15em}
.wfi[hidden],.sprite{display:none}
.pptn .small{color:var(--ink2)}
.pptw a{display:inline-flex;align-items:center;min-height:44px;margin-block:-12px;color:var(--ink);font-weight:700}
/* mobile-qa 2026-11-02: every .plink wraps between words («Cargá la llegada», not «ll / egada»);
   only the invitation's URL (js/invites.js, a <p>) may break anywhere, it has no spaces. */
.plink{overflow-wrap:break-word;font-size:.8rem}
p.plink{overflow-wrap:anywhere}
.hinv h2,.hlater h2{font-size:1.05rem;margin:0 0 8px}
#v-home .invcard h3,#acct .invcard h3{margin:0;font-size:1.1rem;text-transform:none;letter-spacing:0;color:var(--ink);font-weight:700;font-family:inherit}
.invyes[hidden],.invno[hidden]{display:none}
.invrow{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:8px}
/* trip-footer: a link inside the sentence, as the cards' (.hmiss a): the text's ink, the red
   underline; not the browser's blue. */
.hlater a{color:var(--ink);text-decoration-color:var(--red);text-underline-offset:3px}

/* Masthead: the nav-shell bar (G1) is at the end of this sheet, "nav-shell". */
.facts{display:flex;flex-wrap:wrap;gap:4px 18px;font-size:.8rem;color:var(--ink2);padding-block:8px;border-bottom:1px solid var(--hair)}
.facts b{color:var(--ink);font-family:var(--mono);font-weight:500}
.facts .fx-st{color:var(--ink)}   /* D161 (3): the trip's stage, first in the row */

.view{display:none}.view.on{display:block}
/* F14: a section js/model.js renderEmpty() hid (no plan yet) stays hidden even when it is the
   one on screen: under the empty notice there is the notice, not an empty Hoy form. */
.view.on[hidden]{display:none}

/* Map view */
/* D88: the line column is 360 px on desktop (was 400); its header no longer wraps (see .side-h.lh). */
.sheet{display:grid;grid-template-columns:minmax(0,1fr) 360px;gap:0;border-bottom:1px solid var(--hair)}
/* Wide (> 980 px, bug report 2026-10-22): map and line share the 1120 px column, the map
   box is landscape (its width x 0.72, never the window's height: that is D89's phone
   sheet), "Ruta" fills it (fitRegion), the layer legend sits in it and the region chips
   under it as before. The line panel takes the row's height (contain:size: it does not
   size the row, the map does) and scrolls on its own. */
@media (min-width:981px){
  .side{contain:size;max-height:none;height:auto}
}
#map{width:100%;height:100%;display:block;touch-action:none;cursor:grab;background:var(--paper)}
#map,#map text{-webkit-user-select:none;user-select:none}
.side .kj,.side .ro,.line{-webkit-user-select:none;user-select:none}
.toggles,.regions{display:flex;flex-wrap:wrap;gap:4px 14px}
.tg{display:inline-flex;align-items:center;gap:6px;color:var(--ink2)}
.tg::before{content:"";width:10px;height:10px;border:1.5px solid var(--ink2)}
.tg[aria-pressed="true"]{color:var(--ink)}
.tg[aria-pressed="true"]::before{background:var(--ink);border-color:var(--ink)}
.regions button{color:var(--ink2)}
.regions button.on{color:var(--red);font-weight:700}
.zoom{position:absolute;right:12px;top:12px;display:flex;flex-direction:column;border:1.5px solid var(--ink);background:var(--paper)}
.zoom button{width:30px;height:30px;font-size:1.1rem;line-height:1}
.zoom button+button{border-top:1.5px solid var(--ink)}
.scale{position:absolute;left:12px;bottom:12px;font-family:var(--mono);font-size:.7rem;color:var(--ink2);display:flex;flex-direction:column;gap:2px}
.scale i{display:block;height:5px;border:1.5px solid var(--ink);border-top:0}
.key{position:absolute;right:12px;bottom:12px;font-size:.72rem;color:var(--ink2);display:grid;grid-template-columns:auto auto;gap:3px 10px;align-items:center;background:color-mix(in srgb,var(--paper) 88%,transparent);padding:6px 8px}
.key svg{display:block}
.key{display:flex;flex-direction:column;align-items:stretch;gap:2px}
.key.min>:not(.kh){display:none}
.key .kt{display:flex;align-items:center;gap:8px;padding:2px 4px;border-radius:2px;color:var(--ink);text-align:left}
.key .ks{display:flex;align-items:center;gap:8px;padding:2px 4px;color:var(--ink2)}
.key hr{border:0;border-top:1px solid var(--hair);margin:3px 0}
.hint{position:absolute;left:50%;top:12px;transform:translateX(-50%);font-size:.75rem;color:var(--ink2);background:var(--paper);border:1px solid var(--hair);padding:3px 10px;white-space:nowrap}

/* map svg */
.land{fill:var(--land);stroke:var(--landline);stroke-width:.9;vector-effect:non-scaling-stroke;stroke-linejoin:round}
.pref{fill:none;stroke:var(--pref);stroke-width:.7;vector-effect:non-scaling-stroke;stroke-dasharray:2 2}
.sea{font-family:var(--mincho);fill:var(--ink3);letter-spacing:.3em;font-weight:600}
.rt{fill:none;stroke:var(--ida);stroke-width:3.4;vector-effect:non-scaling-stroke;stroke-linecap:round;stroke-linejoin:round}
.rt.back{stroke:var(--vuelta)}
.rt.dt{stroke:var(--dtc);stroke-width:2;stroke-dasharray:1 4.5}
.rt.opt{stroke:var(--ink3);stroke-width:1.2;stroke-dasharray:2 4}
.rt.on{stroke:var(--ink);stroke-width:5}
.rt.dt.on{stroke-width:2.6}
.hit{fill:none;stroke:transparent;stroke-width:16;vector-effect:non-scaling-stroke;cursor:pointer}
.st{cursor:pointer}
.st circle,.st rect{vector-effect:non-scaling-stroke}
.st .ring{fill:var(--white);stroke:var(--ink);stroke-width:2.2}
.st .num{font-family:var(--mono);font-weight:500;fill:var(--ink);text-anchor:middle;dominant-baseline:central;pointer-events:none}
.st.on .ring,.st.hov .ring{fill:var(--red);stroke:var(--red)}
.st.on .num,.st.hov .num{fill:#fff}
.lr{font-family:var(--gothic);font-weight:700;fill:var(--ink2);letter-spacing:.08em;paint-order:stroke;stroke:var(--paper);stroke-linejoin:round;pointer-events:none;text-transform:uppercase}
.pend{fill:var(--red)}
.at{cursor:pointer}
.at rect,.at circle{vector-effect:non-scaling-stroke}
.at .an{font-family:var(--mono);font-weight:500;text-anchor:middle;dominant-baseline:central;pointer-events:none}
.at .al{font-family:var(--gothic);fill:var(--ink);paint-order:stroke;stroke:var(--paper);stroke-linejoin:round;pointer-events:none}
.at.on rect{stroke-width:3}

/* Line column */
.side{min-width:0;display:flex;flex-direction:column;max-height:calc(100vh - 128px);overflow:auto}
.line{padding:14px 0 20px 18px}
.stn{display:grid;grid-template-columns:30px minmax(0,1fr);column-gap:12px;cursor:pointer}
.stn .rail{position:relative;display:flex;justify-content:center}
.stn .dot{width:26px;height:26px;border-radius:50%;border:2.5px solid var(--ink);background:var(--white);display:flex;align-items:center;justify-content:center;font:500 .78rem var(--mono);position:relative;z-index:1}
.stn.air .dot{border-radius:3px;width:18px;height:18px;margin:4px 0;font-size:0}
.stn.stop .dot{width:18px;height:18px;margin:4px 0;transform:rotate(45deg);border-radius:2px;border-color:var(--ink)}
.stn:hover .dot,.stn.on .dot,.stn.hov .dot{background:var(--redbg);border-color:var(--redbg);color:#fff}
.stn .nm{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;padding-top:1px}
.stn .nm .kj{font-size:1.25rem;line-height:1.2}
.stn .nm .ro{font-weight:700;font-size:.82rem;letter-spacing:.06em;text-transform:uppercase;color:var(--ink2)}
.stn .nm .code{font:500 .66rem var(--mono);border:1.5px solid var(--ink);padding:0 4px;border-radius:3px}
.stn .when{grid-column:2;font:.75rem var(--mono);color:var(--ink2)}
.stay{display:grid;grid-template-columns:30px minmax(0,1fr);column-gap:12px}
.stay .bar{justify-self:center;width:8px;background:var(--ink);border-radius:0}
.stay .bar.sak{background:repeating-linear-gradient(180deg,var(--ink) 0 6px,var(--sakura) 6px 9px)}
.stay .in{padding:6px 0 10px;display:flex;flex-direction:column;gap:3px;font-size:.8rem;color:var(--ink2)}
.spur .kj{font-size:.95rem}
.move{display:grid;grid-template-columns:30px minmax(0,1fr);column-gap:12px;cursor:pointer}
.move .bar{justify-self:center;width:3px;background:var(--ida);min-height:34px}
.move.back .bar{background:var(--vuelta)}.move.back .in{color:var(--vuelta)}
.move .in{font:.75rem var(--mono);color:var(--ida);align-self:center;padding:6px 0}
.move:hover .in{text-decoration:underline}
.move.on .bar{width:4px;background:var(--ink)}

/* Station sign detail */
.det{padding:16px 0 28px 18px;display:flex;flex-direction:column;gap:18px}
.sign{border:2.5px solid var(--ink);background:var(--white)}
.sign .top{padding:12px 14px 8px;text-align:center}
.sign .top .kj{font-size:2.4rem;line-height:1.1;display:block}
.sign .top .ro{font-weight:700;letter-spacing:.12em;text-transform:uppercase;font-size:.85rem}
.sign .top .code{display:inline-block;font:500 .7rem var(--mono);border:1.5px solid var(--ink);border-radius:3px;padding:0 5px;margin-bottom:4px}
.sign .nav{display:grid;grid-template-columns:1fr auto 1fr;font-size:.78rem;padding:6px 8px;align-items:center;gap:6px}
.sign .nav button{display:flex;flex-direction:column;align-items:flex-start;min-width:0}
.sign .nav button:last-child{align-items:flex-end;text-align:right}
.sign .nav button .kj{font-size:.95rem}
.sign .nav button span{color:var(--ink2);font-size:.68rem;letter-spacing:.06em;text-transform:uppercase}
.sign .nav button:hover .kj{color:var(--red)}
.sign .nav .here{font:.7rem var(--mono);color:var(--ink2);text-align:center}
.meta{display:grid;grid-template-columns:auto 1fr;gap:4px 14px;font-size:.82rem}
.meta dt{color:var(--ink2)}.meta dd{margin:0}
.sec h3{margin:0 0 6px;font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--ink2);display:flex;justify-content:space-between;align-items:baseline;border-bottom:1px solid var(--hair);padding-bottom:4px}
.sec h3 button{letter-spacing:0;text-transform:none;color:var(--red);font-size:.78rem}
.sec p{font-size:.85rem}
.atr{display:grid;grid-template-columns:34px minmax(0,1fr) auto;gap:8px;align-items:baseline;padding:5px 2px;border-bottom:1px solid var(--hair);cursor:pointer;font-size:.85rem}
.atr:hover,.atr.on{background:var(--redsoft)}
.atr .n{font:500 .68rem var(--mono);text-align:center;border:1.5px solid var(--ink);border-radius:3px;padding:0 2px}
.atr .n.pending{background:var(--redbg);border-color:var(--redbg);color:#fff}
.atr .n.explicit{border-color:var(--red);color:var(--red)}
.atr .n.opt{border-style:dashed;border-color:var(--ink3);color:var(--ink3)}
.atr small{display:block;color:var(--ink2);font-size:.74rem}
.atr .d{font:.72rem var(--mono);color:var(--ink2);white-space:nowrap}
.days{display:flex;flex-direction:column;font-size:.83rem}
.days div{display:grid;grid-template-columns:46px 1fr;gap:8px;padding:3px 0;border-bottom:1px dotted var(--hair)}
.days .k{font:.72rem var(--mono);color:var(--ink2);padding-top:2px}
.days .k.tr{color:var(--red)}
.micro{font-size:.82rem;display:flex;flex-wrap:wrap;align-items:center;gap:2px 6px}
.micro b{font-family:var(--mincho);font-weight:900}
.micro i{color:var(--red);font-style:normal}
.link{color:var(--red);font-weight:700}
.vids{display:flex;flex-direction:column;gap:8px}
.vtag{display:inline-block;font:500 .62rem var(--mono);border:1.2px solid var(--ink2);color:var(--ink2);border-radius:2px;padding:0 4px;margin:3px 4px 0 0}   /* D150 (1) */

/* Distances */
.wrap{padding-block:22px}
.lede,.trlede{max-width:68ch;color:var(--ink2);font-size:.88rem;margin-bottom:18px}
.strip{overflow-x:auto;border-top:2px solid var(--ink);border-bottom:1px solid var(--hair);padding-block:10px}
.strip h3,.wrap h3{margin:0;font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--ink2)}
.strip svg{display:block;min-width:900px;width:100%}
/* D134: at <= 520 px the strips are drawn top to bottom (drawStripV) as wide as the box: no sideways scroll */
@media (max-width:520px){.strip{overflow-x:visible}.strip svg.v{min-width:0}}   /* D211: a leg's mode on Tramos' strip (12 px: 2.6 units ~ a 16 px .mdi's 1.7) */
.ds-red{font-family:var(--mono);fill:var(--red)}
.ledger{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,330px),1fr));gap:0 32px;margin-top:22px}
.ledger .r{display:flex;justify-content:space-between;gap:12px;padding:6px 0;border-bottom:1px solid var(--hair);font-size:.86rem}
/* A value too long for its row (a leg between two long place names, Ritmo → Tramos) wraps
   instead of pushing the page wider (landscape phone, 2026-10-31); one that fits stays on one
   line (it was white-space:nowrap, wrapped only at <= 520 px). */
.ledger .r b{font-family:var(--mono);font-weight:500;text-align:right;min-width:0;overflow-wrap:anywhere}
.ledger .r>span{min-width:0}
.qs{margin-top:26px;max-width:72ch}
.cmp{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr));gap:24px 40px;margin-top:16px}
.cmp h4{margin:0 0 8px;font-size:1rem}
.fare{width:100%;border-collapse:collapse;font-size:.86rem}
.fare caption{text-align:left;font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--ink2);padding:18px 0 6px;border-bottom:2px solid var(--ink)}
.fare td{padding:6px 4px;border-bottom:1px solid var(--hair);vertical-align:top}
.fare td.y{text-align:right;white-space:nowrap;font-family:var(--mono)}
.fare td small{display:block;color:var(--ink2);font-size:.74rem}
.fare .kj{font-size:.95rem}
.fare tr.sum td{font-weight:700;border-bottom:0;padding-top:8px}
.fare tr.off td:not(:first-child){opacity:.4}
.fare input[type=number],.fare input[data-g]{width:76px;font:inherit;font-family:var(--mono);background:var(--paper);color:var(--ink);border:1px solid var(--hair);border-bottom:1.5px solid var(--ink);padding:1px 4px;text-align:right}
.fare input[type=checkbox]{accent-color:var(--red)}
.tot .big{font-family:var(--mono);font-size:2.2rem;color:var(--red);line-height:1.1;margin-top:6px}
.tot .r{display:flex;justify-content:space-between;padding:5px 0;border-bottom:1px solid var(--hair);font-size:.84rem}
.cfx .dbtn{font-size:.78rem;padding:4px 10px}
/* D153: the one "≈ al cambio del dd.mm" of a view, and a frozen estimate in Gastos */
.fxnote{margin:4px 0 0;font-size:.74rem;color:var(--ink2)}
.xt .xfxe input.fxest,.resv input.fxest{color:var(--ink3)}
.resv .fxh{display:block;font-size:.72rem;color:var(--ink2);margin-top:2px}
.notes{margin:10px 0 0;padding-left:18px;font-size:.84rem;display:flex;flex-direction:column;gap:6px;color:var(--ink2)}
.notes b{color:var(--ink)}
.small{font-size:.75rem;color:var(--ink2)}
/* F1/F2: the inline terms/privacy links of the account screens' acceptance line (views/cuenta.js). */
.small[data-legal] a{color:var(--ink);text-underline-offset:2px}
/* E21-11: why the app asks for your own AI (D157/D170), the same note under the AI line of
   Viaje nuevo, the wizard's step 2 and Datos → Prompts. Two classes so .tsec p does not resize it:
   one size and one spacing everywhere, tucked under the line above (which keeps its margin). */
.small.aiwhy{font-size:.8rem;line-height:1.45;max-width:68ch;margin:-6px 0 14px}

.est{font:.62rem var(--mono);color:var(--ink3);margin-left:4px}

/* Bases */
.book{width:100%;border-collapse:collapse;font-size:.85rem;min-width:760px;border-top:2px solid var(--ink)}
.book th{text-align:left;font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;color:var(--ink2);font-weight:700;padding:8px 6px;border-bottom:1px solid var(--ink)}
.book td{padding:8px 6px;border-bottom:1px solid var(--hair);vertical-align:middle}
.book td.m{font-family:var(--mono);white-space:nowrap}
.book .kj{font-size:1.05rem}
.book tr.done td{background:var(--redsoft)}
.book input[type=text]{width:100%;min-width:150px;font:inherit;background:var(--paper);color:var(--ink);border:1px solid var(--hair);border-bottom:1.5px solid var(--ink);padding:2px 6px}
.book input[type=checkbox]{accent-color:var(--red);width:16px;height:16px}
.book .go{color:var(--red);font-weight:700;white-space:nowrap}
.prio{font:500 .68rem var(--mono);border:1.5px solid var(--ink);border-radius:3px;padding:0 4px;white-space:nowrap}
.bcard{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,420px);gap:20px 36px;padding-block:26px;border-top:2px solid var(--ink);margin-top:30px;scroll-margin-top:12px}
.bcard .hd .ro{font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--ink2)}
.bcard .hd .mono{color:var(--ink2);font-size:.82rem}
.bcard .zone{margin-top:12px;font-size:1.05rem;font-weight:700}
.bcard .zone span{color:var(--red)}
.bcard dl{display:grid;grid-template-columns:130px minmax(0,1fr);gap:6px 14px;margin:14px 0 0;font-size:.86rem}
.bcard dt{color:var(--ink2)}
.bcard dd{margin:0}
.bcard ul{margin:4px 0 0;padding-left:18px}
.bmap{border:1px solid var(--hair);background:var(--land);aspect-ratio:4/3;max-width:100%}
.bmap svg{display:block;width:100%;height:100%}
@media (max-width:980px){.bcard{grid-template-columns:1fr}}

@media (max-width:980px){
  .sheet{grid-template-columns:1fr}
  .side{max-height:none;border-top:2px solid var(--ink)}
}
@media (max-width:520px){
  .key{display:none}
}
@media (prefers-reduced-motion:reduce){*{scroll-behavior:auto!important}}


/* Shared-db additions: sync pill, empty state, visited marks, expenses form */
.facts .sync{margin-left:auto;font-family:var(--mono);color:var(--ink3)}
/* E18-18 (C5): THE empty state, the same everywhere: "Todavía no hay X." in a dashed box,
   with the next step at its end when there is one ("algo ›", or «the button's name»).
   #empty is the same box for a whole view (opening a trip, no itinerary), bigger. */
.empty{margin:8px 0;font-size:.88rem;line-height:1.45;color:var(--ink2);border:1.5px dashed var(--hair);padding:12px 14px;list-style:none;overflow-wrap:anywhere}
#empty{margin:40px auto;max-width:60ch;text-align:center;font-size:.95rem;padding:28px 20px}
/* E18-16: the loading bar, on a status line that says something is loading ("Abriendo
   Wayfolio…", "Cargando…"; role="status" on it): an accent segment slides along a hairline
   under the text. The text stays: it is what a screen reader and the human read. The bar
   keeps its room from the start and only fades in after 180 ms, so a short load never
   flashes it and nothing moves when it shows. Reduced motion: no sliding, a slow pulse. */
.loadbar::after{content:"";display:block;width:min(10rem,100%);height:2px;margin-top:8px;opacity:0;
  background:linear-gradient(var(--red),var(--red)) no-repeat var(--hair);background-size:35% 100%;
  animation:lb-in .2s linear .18s forwards,lb-slide 1.3s ease-in-out .18s infinite}
.loadbar:empty::after{content:none}   /* the load ended and blanked the line, the class stayed */
@keyframes lb-in{to{opacity:1}}
@keyframes lb-slide{from{background-position:-60% 0}to{background-position:160% 0}}
@keyframes lb-pulse{from{opacity:1}to{opacity:.35}}
@media (prefers-reduced-motion:reduce){.loadbar::after{background-size:100% 100%;animation:lb-pulse 2.4s ease-in-out .18s infinite alternate}}
/* E18-16: the determinate variant, where the progress is known (a zone saving "N de M",
   js/imap.js): the accent fills --p (0..1) of the hairline from the left, no sliding. */
.loadbar.lbdet::after{background-size:calc(var(--p,0) * 100%) 100%;animation:lb-in .2s linear .18s forwards;transition:background-size .3s ease-out}
@media (prefers-reduced-motion:reduce){.loadbar.lbdet::after{transition:none}}
/* E18-16: while the trip opens the notice is a status, not an empty box: no dashed frame. */
.empty.loadbar{border-color:transparent}
.empty.loadbar::after{margin:14px auto 0}
.atr{grid-template-columns:34px minmax(0,1fr) auto 20px}
.atr input[type=checkbox]{accent-color:var(--dtc);width:16px;height:16px;align-self:center;margin:0}
.atr .n.ok{background:var(--okbg);border-color:var(--okbg);color:#fff}
.atr.done>span:nth-child(2){color:var(--ink2);text-decoration:line-through;text-decoration-color:var(--ink3)}
.fare td .del{color:var(--ink3);font-size:1.1rem;line-height:1;padding:0 4px}
.fare td .del:hover{color:var(--red)}
.fare tr.add td{padding:10px 0 12px}
input:disabled,select:disabled,button:disabled{opacity:.55;cursor:not-allowed}
.thead{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 18px;border-bottom:2px solid var(--ink);padding-bottom:10px}
.thead .tdt{font-size:1.6rem;font-weight:500}
.thead .tn{color:var(--ink2);font-size:.88rem}
.thead .tcount{font-size:2.2rem;color:var(--red);line-height:1.1}
.tsec{padding-top:20px}
/* E18-18 (C10): the app's one section title, grey caps at .72rem (11.5 px) with its hairline;
   every view's h3 (.sec, .wrap, .tsec, .estay, .shsec, Costos' .csh, Mis viajes' .hbar/.heye,
   the summary's, Capas') is this size, and every inner h4 is .tsec h4's .7rem. */
.tsec h3{margin:0 0 8px;font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--ink2);display:flex;flex-wrap:wrap;justify-content:space-between;align-items:baseline;gap:2px 10px;border-bottom:1px solid var(--hair);padding-bottom:4px}   /* wrap: a long state word at 200 % text goes under the title (mobile-qa 2026-11-02) */
.tsec h4{margin:14px 0 4px;font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;color:var(--ink2)}
.tsec p{font-size:.9rem}
.tcard{border:2.5px solid var(--ink);background:var(--white);padding:12px 14px}
.tch{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px}
.tch .kj{font-size:1.9rem;line-height:1}
.tch .ro{font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ink2)}
.thotel{font-size:1.05rem;font-weight:700;margin-top:8px;overflow-wrap:anywhere}
.muted{color:var(--ink3);font-weight:400}
.tkv{display:grid;grid-template-columns:auto minmax(0,1fr);gap:4px 14px;font-size:.86rem;margin:8px 0 0}
.tkv dt{color:var(--ink2)}.tkv dd{margin:0;min-width:0;overflow-wrap:anywhere}
.tact{display:flex;flex-wrap:wrap;gap:4px 16px;margin-top:6px}
.tchg{border-left:3px solid var(--red);padding:6px 10px;margin-bottom:10px;font-size:.88rem}
.tleg{border-top:1px solid var(--hair);padding:8px 0;font-size:.88rem;overflow-wrap:anywhere}
.tleg .tl2{color:var(--ink2);font-size:.8rem}
.tleg .tl3{font-size:.82rem;margin-top:2px}
.tat .tkj{font-size:.82rem;color:var(--ink2)}
.pill{display:inline-block;font:500 .68rem var(--mono);border:1.5px solid var(--ink);border-radius:3px;padding:0 5px;white-space:nowrap}
.pill.ok{background:var(--okbg);border-color:var(--okbg);color:#fff}
.pill.no{border-color:var(--red);color:var(--red)}
/* Place type badges in Lugares and the place sheet, in the route map's colours: base red
   (the accent), day trip green (the dotted day-trip lines), route stop blue (the return
   line), optional grey and dashed (no fixed date yet). Text and border carry the colour
   (>= 4.5:1 on the paper in both themes); the fill is a faint tint. */
.pill.pt-base{color:var(--red);border-color:var(--red);background:var(--redsoft)}
.pill.pt-dayTrip{color:var(--dtct);border-color:var(--dtct);background:color-mix(in srgb,var(--dtc) 12%,transparent)}
.pill.pt-routeStop{color:var(--vuelta);border-color:var(--vuelta);background:color-mix(in srgb,var(--vuelta) 10%,transparent)}
.pill.pt-optional,.pill.pt-airport{color:var(--ink2);border-color:var(--ink2);border-style:dashed}
.texpf input,.texpf select,#t-notes,.tsimrow input,.resv input,.lres input[type=text]{font:inherit;background:var(--paper);color:var(--ink);border:1px solid var(--hair);border-bottom:1.5px solid var(--ink);padding:6px 8px;min-width:0;width:100%}
.tsimctl{margin-top:26px;font-size:.82rem;color:var(--ink2)}
.tsimctl summary{cursor:pointer}
.tedit{margin-top:10px;font-size:.84rem}
.tedit summary{cursor:pointer;color:var(--ink2)}
/* Climate (schema 1.3) */
/* Hoy: the typical weather is a row of chips per place since D87 (block "Hoy" at the end). */
.clchart{margin-top:6px}
.clchart svg{display:block;width:100%;height:auto}
.cl-tx{fill:none;stroke:var(--red);stroke-width:2;stroke-linejoin:round}
.cl-tn{fill:none;stroke:var(--vuelta);stroke-width:2;stroke-linejoin:round}
.cl-bar{fill:var(--vuelta);opacity:.28}
.cl-grid{stroke:var(--hair);stroke-width:1}
.cl-lab{font-family:var(--mono);font-size:9px;fill:var(--ink2)}
.cl-key{display:flex;flex-wrap:wrap;gap:2px 12px;font-size:.72rem;color:var(--ink2);margin-top:2px}
.cl-key i{display:inline-block;width:14px;height:3px;vertical-align:middle;margin-right:4px}
.cltab-w{overflow-x:auto}
.cltab{width:100%;border-collapse:collapse;font-size:.8rem;margin-top:6px}
.cltab th{text-align:left;font-weight:700;color:var(--ink2);font-size:.64rem;letter-spacing:.1em;text-transform:uppercase;border-bottom:1px solid var(--ink);padding:3px 4px}
.cltab td{padding:3px 4px;border-bottom:1px solid var(--hair);font-family:var(--mono);white-space:nowrap}
.rnw{height:12px;display:flex;justify-content:center;align-items:center}
.rnw .rn{flex:none}
.rn{display:inline-block;border-radius:50%;background:var(--vuelta)}
.rn.r0{width:3px;height:3px;opacity:.45}.rn.r1{width:5px;height:5px;opacity:.7}.rn.r2{width:7px;height:7px}.rn.r3{width:9px;height:9px}
/* Maps links and booking fields (Hoy, Bases, Costos, detail) */
.maplink{color:var(--red);font-weight:700;font-size:.8rem;white-space:nowrap;text-decoration:none}
.maplink:hover{text-decoration:underline}   /* open: its own line under the links, wrapping */
.mmore>summary{display:inline;cursor:pointer;list-style:none;font-size:.76rem;color:var(--ink2);white-space:nowrap}
.chk{display:inline-flex;align-items:center;gap:8px;cursor:pointer}
.chk input{accent-color:var(--dtc);width:18px;height:18px;margin:0}
.resv{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,150px),1fr));gap:8px 12px;margin-top:8px;align-items:end}
.resv label{display:flex;flex-direction:column;gap:2px;font-size:.78rem;color:var(--ink2);min-width:0}
.resv label.chk{flex-direction:row;color:var(--ink)}
.resv-wrap h4{margin:0;font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;color:var(--ink2)}
.lres{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px;margin-top:4px;font-size:.78rem}
/* width 0 + flex-basis: 140 px or more on screen, but no 20-character intrinsic width in the
   table's min-content (WebKit counted it and Presupuesto's fares overflowed a phone, tester d148-d161 B12). */
.lres input[type=text]{width:0;min-width:0;flex:1 1 140px;padding:2px 6px}
.bmap-l .maplink{margin-left:auto;font-size:.72rem}
@media (max-width:520px){.thead .tcount{font-size:1.6rem}.thead .tdt{font-size:1.45rem}}
@media (pointer:coarse),(max-width:640px){
  #v-today input,#v-today select,#v-today button,.resv input,.lres input,.tbtn{min-height:44px}
  .maplink,.mdir,.mother,.mmore>summary,.chk,.tedit summary,.tsimctl summary,.tsim button,.tex .del{min-height:44px;display:inline-flex;align-items:center}
  .chk input{width:24px;height:24px}
}
@media (max-width:520px){
  .facts{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;white-space:nowrap;gap:0 14px;padding-block:6px}
  .facts::-webkit-scrollbar{display:none}
  .facts>span{flex:none}
  /* day trips, stops and nights at the end are in Bases and Ritmo; the scrolling row keeps nights, hotels, booked, visited and sync */
  .facts>span.fx-x{display:none}
  .today{padding-top:10px}
}

/* D48: touch targets on touch screens (iPhone). The only CSS added to the reference
   besides the shared-db block above, and it never applies to a mouse/trackpad
   (pointer: fine), so the desktop layout is untouched. It only grows the tappable box of
   existing controls to >= 44 px (Apple HIG); no reference rule is edited. */
@media (pointer: coarse){
  .zoom button{width:44px;height:44px}
  .toggles,.regions{row-gap:0}
  .regions button,.toggles button{min-height:44px}
  .regions button{min-width:44px}
  .side-h button,.sec h3 button,.sign .nav button,.book .go{min-height:44px}
  .book input[type=text],.fare input[type=number],.fare input[data-g],.assume input,.texpf input,.texpf select,.texpf button{min-height:44px}
  .fare td .del{min-width:44px;min-height:44px}
  /* Checkboxes: a native checkbox is drawn at the size of its box (padding and border are
     ignored), so a 44 px box would be a 44 px square. Instead the box is 44 px and
     transparent, and the visible 22 px square is painted in its centre: the box of
     .tg::before (1.5 px ink2 outline) when off, the reference accent colour with a check
     when on. Same colours as the native control: green on attractions, red elsewhere. */
  .atr input[type=checkbox],.book input[type=checkbox],.fare input[type=checkbox]{
    --cb:var(--red);-webkit-appearance:none;appearance:none;position:relative;flex:none;
    width:44px;height:44px;margin:0;border:0;border-radius:0;cursor:pointer;
    background:linear-gradient(var(--white),var(--white)) center/19px 19px no-repeat,
               linear-gradient(var(--ink2),var(--ink2)) center/22px 22px no-repeat}
  .atr input[type=checkbox]{--cb:var(--dtc);margin-block:-5px}  /* eat the row padding: rows stay 44 px */
  .atr input[type=checkbox]:checked,.book input[type=checkbox]:checked,.fare input[type=checkbox]:checked{
    background:linear-gradient(var(--cb),var(--cb)) center/22px 22px no-repeat}
  .atr input[type=checkbox]:checked::after,.book input[type=checkbox]:checked::after,.fare input[type=checkbox]:checked::after{
    content:"";position:absolute;left:50%;top:50%;width:6px;height:11px;border:solid var(--paper);
    border-width:0 2.5px 2.5px 0;transform:translate(-50%,-62%) rotate(45deg)}
  .atr{grid-template-columns:34px minmax(0,1fr) auto 44px}
  /* Hoy, Maps links and booking editors (mockup 2026-10-19, D78). The mockup's own
     `(pointer:coarse),(max-width:640px)` block already gives 44 px of height to every
     input/select/button of #v-today (quick expense, notes, date simulation), to the
     .resv/.lres inputs of the stay and leg editors, to .maplink, .chk and the summaries;
     this adds only what it leaves short. Width: the new "Hoy" tab, "Maps" in the Bases
     list and the "×" of an expense of the day are narrower than 44 px. */
  .maplink,.mdir,.mother,.mmore>summary,.tex .del,.tsim button{min-width:44px;justify-content:center}
  /* .chk checkboxes (Hoy attractions, "reservado" of the stay and leg editors): the
     mockup draws them at 24 px here; same technique as the checkboxes above, a 44 px
     transparent box with the 24 px square painted in its centre (attraction green, as
     the mockup's accent-color), and -10 px margins so it takes the 24 px the mockup
     lays out: rows and labels keep the mockup's geometry. */
  .chk input[type=checkbox]{-webkit-appearance:none;appearance:none;position:relative;flex:none;
    width:44px;height:44px;margin:-10px;border:0;border-radius:0;cursor:pointer;
    background:linear-gradient(var(--white),var(--white)) center/21px 21px no-repeat,
               linear-gradient(var(--ink2),var(--ink2)) center/24px 24px no-repeat}
  .chk input[type=checkbox]:checked{background:linear-gradient(var(--dtc),var(--dtc)) center/24px 24px no-repeat}
  .chk input[type=checkbox]:checked::after{content:"";position:absolute;left:50%;top:50%;width:6px;height:11px;
    border:solid var(--paper);border-width:0 2.5px 2.5px 0;transform:translate(-50%,-62%) rotate(45deg)}
}

/* D74 (deliberate deviation from the mockup, decided by the human): at <= 520 px the
   reference does not draw the legend (.key{display:none} in its max-width:520px block), so
   the Day trips / rail network switches come back to the bottom bar #toggles, and only there.
   Same breakpoint as that rule; inline-flex is the display of every .tg. Their touch size
   comes from the D48 block (.toggles button). */
.tg.narrow{display:none}
@media (max-width:520px){.tg.narrow{display:inline-flex}}
/* D120: the rail and season switches exist only with a map package that has those layers
   (js/geo.js paintMapTexts() sets [hidden]); the display rules above must not bring them back. */
.tg[hidden]{display:none!important}
/* iOS Safari reads two quick taps on a control as a double-tap zoom and drops the second
   click (switching a layer off and on again, or two chips in a row); the map's controls
   opt out of that gesture. Pinch zoom of the page is untouched. */
.toggles button,.regions button,.key .tg,.zoom button,.side-tg,.mlayers,.imkinds button{touch-action:manipulation}

/* D77 at <= 520 px (mockup 2026-10-19 16:32): .facts is a one-line row that scrolls
   sideways there, so it clips its content vertically too. data.js grows the #sync pill
   by var(--sync-pad, 13px) above and below (with equal negative margins); in this row
   that would only add a few px of vertical scroll, so the pill takes exactly the row's
   padding-block (6 px in the mockup's rule): it fills the row's height, nothing more. */
@media (max-width:520px){.facts{--sync-pad:6px}}

/* ===== UI iteration in web/ (D84-D90) ============================================== */

/* D147 (replaces D85/D96's fixed 1120 px column): one centred, fluid container shared by
   the masthead (with the nav), the facts row, the clock fold and every view, so the tabs
   never jump sideways and the map lines up with the masthead. Its width is
   min(100% - 2 gutters, clamp(1120px, 88vw, 1760px)): the gutters are the body's padding
   (16 px or the safe area), so max-width does the min(). Below 1152 px (1120 + the
   gutters) it is the whole width and nothing changes (the nav-shell bar uses it too).
   Type is never scaled with vw. From
   1440 px the views spend the width on more columns (the "D147 wide" block at the end). */
body{--maxw:clamp(1120px,88vw,1760px)}
.view{max-width:var(--maxw);margin-inline:auto}
.facts{max-width:var(--maxw);margin-inline:auto}
#t-clim:empty{display:none}
/* D91 (replaces the D87 chips): a weather widget with no box, no chip and no background.
   Per place: the name in small caps; a line icon (28 px, 1.6 px stroke in currentColor =
   --ink2, built by paintWx()) with max / min in the title face, the minimum dimmed; below,
   one small --ink2 line. Two places side by side on wide screens (two grid columns, a third
   wraps under them), stacked at <= 640 px. On wide screens the widget sits on the right
   of the day title, bottom-aligned with it, as the chips did. */
.tclim{display:grid;grid-template-columns:repeat(2,auto);gap:10px 32px;margin-left:auto}
.tclim.one{grid-template-columns:auto}
.crow{display:flex;flex-direction:column;align-items:flex-start;gap:1px;min-width:0}
.cpl{font-family:var(--gothic);font-size:.8rem;font-variant-caps:all-small-caps;letter-spacing:.08em;color:var(--ink2)}
.cnow{display:flex;align-items:center;gap:8px}
.cwx{display:inline-flex;flex:none;color:var(--ink2)}
.wxi{display:block;overflow:visible}
.wxi .occ{fill:var(--paper)}
.ctemp{font-family:var(--mincho);font-size:1.35rem;font-weight:600;line-height:1.15;color:var(--ink);white-space:nowrap}
.ctemp .tmin{color:var(--ink2)}
.cline{font-family:var(--gothic);font-size:.74rem;color:var(--ink2);line-height:1.4}
@media (max-width:640px){.tclim{grid-template-columns:auto;justify-content:start;margin-left:0}}
@media (max-width:640px){.tplanb{justify-content:flex-start}}
/* D91: the same icon, 20 px, at the start of each row of "Clima en tu visita". */
.cltab .cday{display:inline-flex;align-items:center;gap:6px}
.cltab .cwx.sm{margin-block:-2px}
/* D156: a secondary control under the hero: smaller type, a hairline border. */
/* C11 (E18-18): "‹ Anterior" / "Siguiente ›" is one component, these boxes, in Hoy and in a
   place's sheet (.pnav). */
.dnav{display:inline-flex;align-items:center;justify-content:center;gap:6px;font-size:.76rem;font-weight:700;color:var(--ink2);border:1px solid var(--hair);padding:2px 10px}
.dnav small{font:400 .72rem var(--mono);color:var(--ink2)}
.dnav:hover:not(:disabled){background:var(--ink);color:var(--paper)}
.dnav:hover:not(:disabled) small{color:var(--paper)}
.dnav[hidden]{display:none}
@media (max-width:520px){.dnav small{display:none}.dnav{padding-inline:14px}}
@media (max-width:520px){
  body.fit{padding-bottom:0}
  body.fit .sheet{display:flex;flex-direction:column;border-bottom:0;padding-bottom:env(safe-area-inset-bottom,0px)}
  body.fit .regions,body.fit .toggles{flex-wrap:nowrap;overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none;white-space:nowrap;gap:0 16px;
    margin-left:calc(-1 * max(16px,env(safe-area-inset-left,0px)));margin-right:calc(-1 * max(16px,env(safe-area-inset-right,0px)));
    padding-left:max(16px,env(safe-area-inset-left,0px));padding-right:max(16px,env(safe-area-inset-right,0px))}
  body.fit .regions::-webkit-scrollbar,body.fit .toggles::-webkit-scrollbar{display:none}
  body.fit .regions>*,body.fit .toggles>*{flex:none}
  body.fit .side{display:none;flex:0 0 54%;min-height:0;max-height:none;border-top:1px solid var(--hair)}
  /* the centred one-line hint ran under the zoom buttons at 390 px */
  .hint{left:12px;right:64px;transform:none;white-space:normal;text-align:center}
}
#dkey-rain[hidden]{display:none}
.rgh .kj{font-size:1.35rem;line-height:1}
.rgh .mono{font-size:.75rem;color:var(--ink2)}
.rrow{display:grid;grid-template-columns:76px 104px minmax(0,1fr) 150px 16px 44px 44px;align-items:center;gap:0 14px;width:100%;min-height:44px;padding:7px 6px;
  border-bottom:1px solid var(--hair);text-align:left;font-size:.86rem}
.rrow:hover{background:var(--redsoft)}
.rrow.on{background:var(--redsoft);box-shadow:inset 3px 0 0 var(--red)}
.rd{font-family:var(--mono);font-size:.8rem;white-space:nowrap;display:flex;flex-direction:column;line-height:1.25}
.rd b{font:700 .66rem var(--gothic);letter-spacing:.1em;text-transform:uppercase;color:var(--red)}
.kb{display:inline-flex;align-items:center;gap:5px;max-width:100%}
.kb::before{content:"";flex:none;width:9px;height:9px;border:1.5px solid var(--ink)}
.kb.k-transfer::before{background:var(--ida);border-color:var(--ida)}
.kb.k-back::before{background:var(--vuelta);border-color:var(--vuelta)}
.kb.k-dayTrip::before{background:var(--dtc);border-color:var(--dtc)}
.kb.k-flex::before,.kb.k-optional::before{background:repeating-linear-gradient(135deg,var(--ink3) 0 1.5px,transparent 1.5px 4px);border-color:var(--ink3)}
.kb.k-slow::before{border-style:double;border-width:3px}
.kb.k-arrival::before{background:var(--ink3);border-color:var(--ink3)}
.rs{min-width:0;overflow-wrap:anywhere}
.rs small{display:block;color:var(--ink2);font-size:.76rem}
.rt{display:flex;align-items:center;gap:6px;min-width:0}
.rt .tr{flex:1 1 auto;height:8px;background:var(--land);position:relative;min-width:0}
.rt .tr i{position:absolute;left:0;top:0;bottom:0;background:var(--ink3)}
.rt .tr i.k-transfer{background:var(--ida)}.rt .tr i.k-back{background:var(--vuelta)}.rt .tr i.k-dayTrip{background:var(--dtc)}
.rt em{flex:none;width:4.6em;white-space:nowrap;text-align:right;font:normal .72rem var(--mono);color:var(--ink2)}
.rv{font-family:var(--mono);font-size:.76rem;color:var(--ink2);text-align:right}
.rv.all{color:var(--dtct);font-weight:500}
@media (max-width:640px){
  .rrow{grid-template-columns:auto auto minmax(0,1fr) 14px 34px 44px;grid-template-areas:"d k t r v x" "d s s s s x";gap:2px 8px;padding-inline:4px}
  .rd{grid-area:d;align-self:start}.rt{grid-area:t}.rrow>.rnw{grid-area:r}.rv{grid-area:v}.rs{grid-area:s}.rx{grid-area:x}   /* D163 (a): .rx */
}
/* D92: a Ritmo row is a div (it holds a place link); its "open in Hoy" button covers it
   and the link sits above that button. */
.rrow{position:relative}
.rhit{position:absolute;inset:0;z-index:1;width:100%;height:100%}
.rrow .plink.in{position:relative;z-index:2}
.rgh .plink{display:inline-flex;align-items:baseline;flex-wrap:wrap;gap:2px 10px;text-align:left}

/* ===== D92/D93: place sheet (#v-place) ============================================= */
/* Place links (Hoy, Ritmo, the sheet): the place name in its own type, a red › after the
   block ones; inline ones (inside a sentence) are red like .link. */
.plink{text-align:left;color:inherit}
.plink .pgo{color:var(--red);font-weight:700;font-family:var(--gothic);font-size:1rem}
.plink:hover .ro,.plink:hover .kj{color:var(--red)}
.plink.in{display:inline;color:var(--red);font-weight:700}
.plink.in:hover{text-decoration:underline}
.plink.in .kj{font-weight:900}
.tch .plink{display:inline-flex;align-items:baseline;flex-wrap:wrap;gap:4px 10px}
.pfbtn{border:1.5px solid var(--ink);padding:6px 12px;font-weight:700;font-size:.84rem;text-align:center}
#p-body{display:contents}
.pback{font-weight:700;font-size:.9rem;color:var(--red);padding:2px 0}
.pback:hover{text-decoration:underline}
.phead .pkj{font-size:3.2rem;line-height:1}
.pfacts .pill{color:var(--ink)}
.pclimw>.small{margin-bottom:6px}
/* The map (D160): the place's vector drawing (js/vector-map.js placeMap(), the zone maps' renderer
   and classes: .zmap .zbg, .zrail...) in a 4:3 box, 1 unit = 1 CSS px, all in the theme's
   tokens, the OSM credit over its bottom right as in Bases; without a file the same box
   with the points only (.nomap). Under it the Google Maps link. The markers (.pm) are the zone map's attraction circles
   (.zat) with a 44 px hit area: red while pending, muted once visited, the selected one
   larger and outlined in --ink. */
.pmap{margin:18px 0 0;max-width:640px;--pm-ink:var(--ink);--pm-halo:var(--land)}
/* no border: the box must keep the exact aspect of the map (aspect-ratio counts borders), or the <svg> would scale by its height and the points drift; the hairline is an outline */
.pm-box{position:relative;width:100%;aspect-ratio:4/3;background:var(--land);outline:1px solid var(--hair);outline-offset:-1px;overflow:hidden}
.pm-svg{position:absolute;inset:0;width:100%;height:100%;display:block;overflow:hidden}
.pmap figcaption{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:0 12px;font-size:.68rem;color:var(--ink3);margin-top:2px}
.pmap figcaption .pm-cap{margin-left:auto;text-align:right}
.pm-box .pm-attr{z-index:1}   /* the OSM credit over the map's bottom right, Bases' .bmap-attr */
.pm-go{font:700 .72rem/1.3 var(--gothic);color:var(--ink);text-decoration:none;display:inline-flex;align-items:center}
.pm-go:hover,.pm-go:focus-visible{color:var(--red)}
@media (pointer:coarse),(max-width:640px){.pm-go{min-height:44px;padding-right:8px}}
.pm{cursor:pointer;outline:none}
.zmap .pm.zat .hit{fill:transparent;stroke:none}   /* over .zmap .zat.done circle */
.zmap .pm .b{stroke-width:1.5}
.zmap .pm.on .b{stroke:var(--ink);stroke-width:2.5}
.zmap .pm:focus-visible .b{stroke:var(--ink);stroke-width:2.5}
.pm .nn{font-weight:600;text-anchor:middle;dominant-baseline:central;pointer-events:none}
.zmap .zst.zplan{stroke-width:2}
.pm-lead{stroke:var(--pm-ink);stroke-width:1.2}
.pm-dot{fill:var(--red);stroke:var(--pm-halo);stroke-width:1}
.zmap .pm-l{font-weight:400}
.patr{display:grid;grid-template-columns:28px minmax(0,1fr) auto;gap:2px 10px;align-items:start;padding:8px 4px;border-bottom:1px solid var(--hair);font-size:.9rem;cursor:pointer;overflow-wrap:anywhere}
.patr:hover,.patr.on{background:var(--redsoft)}
.patr.on{box-shadow:inset 3px 0 0 var(--red)}
.pn{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;background:var(--redbg);color:#fff;font:600 .74rem var(--mono)}
.pn.ok{background:var(--dtc)}
.pn.off{background:none;border:1.5px dashed var(--ink3);color:var(--ink3)}
.patr small{display:block;color:var(--ink2);font-size:.78rem}
.patr .pakj{font-size:.82rem;color:var(--ink2)}
.patr.done b{color:var(--ink2);text-decoration:line-through;text-decoration-color:var(--ink3)}
.patr .chk{font-size:.78rem;color:var(--ink2)}
/* ===== D163 (a): the list of the day (js/day-route.js) and the opening hours =====
   Between two stops a light line (walk or transport, "Cómo llegar ›"); the place sheet's
   number badge (.pn) on Hoy's rows too; hours under the name, red when closed. */
.dleg .maplink,.dacts .maplink{font-size:.76rem}
.dacts .dobtn{font-size:.8rem;padding:4px 12px}
.dacts .dmapb{font-size:.8rem;padding:4px 12px}   /* D171 (round 4): the day on the interactive map */
@media (pointer:coarse),(max-width:640px){.dacts .dmapb,.imback{min-height:44px}}
.hrs{display:block;font-size:.76rem;color:var(--ink2)}
.hrs.bad{color:var(--red);font-weight:700}
.hrs.unk{color:var(--ink3)}
.hwarn{color:var(--red);font-weight:700;font-size:.84rem;margin:2px 0 6px}
/* Ritmo → Días: the row's ▸ (above its "open in Hoy" button) and the unfolded day under it. */
.rx{display:flex;justify-content:flex-end;min-width:0}
.rexp{position:relative;z-index:2;min-width:36px;min-height:36px;display:inline-flex;align-items:center;justify-content:center;color:var(--red);font-weight:700;font-size:1rem;border:1.5px solid var(--hair)}
.rexp:hover,.rexp[aria-expanded="true"]{border-color:var(--red)}
.dstop .tkj{font-size:.8rem;color:var(--ink2)}
@media (pointer:coarse),(max-width:640px){.rexp{min-width:44px;min-height:44px}}
.pdh{font:700 .7rem var(--gothic);letter-spacing:.12em;text-transform:uppercase;color:var(--ink2);margin:6px 0 2px;padding-bottom:4px;border-bottom:1px solid var(--hair)}
.pleg .pld{font-size:.74rem;color:var(--ink2);padding-top:8px;border-top:1px solid var(--hair)}
#p-notes{font:inherit;background:var(--paper);color:var(--ink);border:1px solid var(--hair);border-bottom:1.5px solid var(--ink);padding:6px 8px;width:100%;resize:vertical;min-height:96px;display:block}
@media (max-width:980px){
  .pmap{margin-inline:auto}
}
@media (max-width:520px){
  .phead .pkj{font-size:2.5rem}
  .patr .chk span{display:none}
  /* the map bleeds to the screen edges, like Mapa (D89) */
  .pmap{margin-left:calc(-1 * max(16px,env(safe-area-inset-left,0px)));margin-right:calc(-1 * max(16px,env(safe-area-inset-right,0px)));max-width:none}
  .pm-box{outline:0}
  .pmap figcaption{padding-left:max(16px,env(safe-area-inset-left,0px));padding-right:max(16px,env(safe-area-inset-right,0px))}
}
/* D48 on the new controls: 44 px boxes on touch screens. */
@media (pointer:coarse),(max-width:640px){
  .pback,.pfbtn,.plink{min-height:44px}
  .pback{display:inline-flex;align-items:center}
  /* An inline link keeps its sentence's lines: its 44 px box is padding cancelled by equal
     negative margins, so the line box only sees the text (place names do not wrap). */
  .plink.in{display:inline-block;min-width:44px;text-align:center;padding:13px 6px;margin:-13px -6px}
  .rgh .plink,.tch .plink{align-items:center}
  #p-notes{min-height:120px}
}
/* ===== D100-D103: payments, dollars and the Costos sections ========================= */
/* The six sections. */
.csec{margin-top:30px}
.csh{display:flex;align-items:baseline;gap:10px;margin:0;border-bottom:1px solid var(--hair);padding-bottom:4px}
.wrap h3.csh{font-size:.72rem;color:var(--ink2)}
.csh .csn{font:700 .72rem var(--mono);color:var(--red);letter-spacing:0}
.csec h4{margin:16px 0 0;font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;color:var(--ink2)}
.csec .fare caption{padding-top:14px;border-bottom-width:1px}
/* Expense rows: date, concept, place, yen, US$, delete; narrow screens fold date and
   place under the concept and the dollars under the yen (.xs copies, hidden when wide). */
.xt th{text-align:left;font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;color:var(--ink2);font-weight:700;padding:6px 4px 4px;border-bottom:1px solid var(--ink)}
.xt th.y,.xt th.xu{text-align:right}
.xt .uest,.xt td.xu.uest{color:var(--ink2)}
.xt td .xs{display:none}.xt td.y,.xt th.y{width:92px}
@media (max-width:640px){
  .xt thead,.xt .xd,.xt .xl,.xt .xu{display:none}
  .xt td .xs{display:block}
}
/* Hotel bookings inside section 2. */
.rsvl{margin-top:6px}
.rsvi{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(150px,200px);gap:4px 18px;padding:8px 0;border-bottom:1px solid var(--hair);font-size:.86rem;align-items:start}
.rsvi b{overflow-wrap:anywhere}
.rsvi small{display:block;color:var(--ink2);font-size:.76rem}
.rsvm{font-family:var(--mono);text-align:right;white-space:nowrap}
.rsvm small{font-size:.76rem}
.rsvi.dup .rsvm{color:var(--ink3)}
.rsvs{display:flex;flex-direction:column;align-items:flex-start;gap:2px}
.rsvs .past{text-decoration:line-through;text-decoration-color:var(--ink3)}
.rsvl .ledger{margin-top:8px}
@media (max-width:640px){.rsvi{grid-template-columns:minmax(0,1fr) auto}.rsvs{grid-column:1/-1;flex-direction:row;flex-wrap:wrap;align-items:baseline;gap:2px 10px}}
/* Payment badges (Bases, Hoy, Costos, place sheet): paid = green, card = grey, at the hotel = outline, to pay = red outline. */
.pill.pay-paid{background:var(--okbg);border-color:var(--okbg);color:#fff}
.pill.pay-card{background:var(--land);border-color:var(--ink3);color:var(--ink2)}
.pill.pay-hotel{background:none;border-color:var(--ink);color:var(--ink)}
/* Tester d100-d104 #4: white on the dark theme's green is 2.24:1; the dark paper is ~8:1. */
/* Tester d105-d106 B10: white on the light theme's green (--dtc) is 4.28:1; the "paid" and
   "ok" pills take a darker green there (#2b8254, 4.75:1). The dark theme keeps --dtc. */
:is(.pill.ok,.pill.pay-paid){background:#2b8254;border-color:#2b8254}
:root[data-theme="dark"] :is(.pill.ok,.pill.pay-paid){color:var(--paper);background:var(--dtc);border-color:var(--dtc)}
/* Tester #5: a concept with no spaces (a pasted URL) wraps instead of widening the page. */
.xt td{overflow-wrap:anywhere}
/* A booking-editor field that refused a value says why (fieldMsg() in js/views/costos.js). */
.resv .ferr{color:var(--red);font-size:.74rem}
.pill.pay-due{background:none;border-color:var(--red);color:var(--red)}
/* Booking editor: the payment select looks like its inputs. */
.resv select{font:inherit;background:var(--paper);color:var(--ink);border:1px solid var(--hair);border-bottom:1.5px solid var(--ink);padding:6px 8px;min-width:0;width:100%}
@media (pointer:coarse),(max-width:640px){.resv select{min-height:44px}}
/* ===== D106: flights (Costos > Vuelos, Hoy "Tu vuelo", Ritmo) ======================= */
.plane{display:inline-block;vertical-align:-2px;flex:none}
#t-fly:empty,#c-fly:empty{display:none}
/* ===== D156: Hoy as the timeline of the day ==========================================
   Events (#t-ev): one row each, a check for the done ones (muted), the one in course with
   a red bar on the left and bold, the future ones as they are; the state small after the
   title ("· en 6 h", "· en curso · faltan 2 h 30", "· hecho"). A stop inside a flight is
   a smaller row. Before the trip the flight is one line (#t-fly .fline) whose summary
   folds the D106 card; "Primer día: ver ›" (#t-go); after the trip, the summary (#t-end). */
#t-ev:empty,#t-go:empty,#t-end:empty,#t-sleep:empty,#t-do:empty,#t-next:empty{display:none}
.tev .evcode{font-size:1.05rem;color:var(--ink)}
.tev .evl,.tgo .plink.in{color:var(--red);font-weight:700;text-decoration:none;white-space:nowrap}
.tev .evl:hover{text-decoration:underline}
.fdet>.fcard{margin-top:8px}   /* D159: "·" ends the text, "ver detalle ›" wraps alone */
.fline>.fcard{margin-top:8px}
.tgo{margin:0}
/* Costos: the booking line, one small line per journey. */
.rsvi.fly .fjl{display:block;font-family:var(--mono);font-size:.76rem;color:var(--ink);overflow-wrap:anywhere;margin-top:2px}
.rsvi.fly .fjk{font-family:var(--gothic);font-weight:700;font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;color:var(--ink2);margin-right:4px}
#c-fly>h4{margin-top:16px}
/* Hoy: the card. Route and state on top, then the segments as two points (time, airport,
   date and zone) with the stop and the connection between them. */
.fcard{margin-bottom:4px}
.fcard+.fcard{margin-top:12px}
.froute{font-size:1.25rem;font-weight:500;line-height:1.2;overflow-wrap:anywhere}
.froute .plane{width:18px;height:18px;vertical-align:-1px;color:var(--red)}
.pill.fst{border-color:var(--red);color:var(--red)}
.fcard .tchg{margin:10px 0 0}
.fsegs{margin-top:10px;border-top:1px solid var(--hair)}
.fseg{padding:8px 0;border-bottom:1px solid var(--hair)}
.fsh{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 10px;font-size:.86rem}
.fsh span{color:var(--ink2);font-size:.8rem}
.fpt{display:grid;grid-template-columns:3.4em minmax(0,1fr);gap:0 10px;align-items:baseline;margin-top:6px;font-size:.9rem}
.fpt .ft{font-size:1.05rem;font-weight:500}
.fpl{min-width:0;overflow-wrap:anywhere}
.fpl small{display:block;color:var(--ink2);font-size:.76rem}
.fstop{margin:6px 0 0 calc(3.4em + 10px);padding-left:10px;border-left:2px dotted var(--ink3);font-size:.82rem;color:var(--ink2);overflow-wrap:anywhere}
.fstop b{color:var(--ink)}
.fstop small{display:block;font-size:.76rem}
.fnote{margin:6px 0 0;font-size:.82rem;color:var(--red)}
.fcon{padding:6px 10px;margin:0;font-size:.84rem;background:var(--land);border-bottom:1px solid var(--hair)}
.fnotes{margin:10px 0 0;padding-left:18px;font-size:.8rem;color:var(--ink2)}
.fnotes li+li{margin-top:2px}
/* Tester d105-d106 B4: flight texts come from the human's tool (notes, flight numbers,
   aircraft, labels, cabin, payment method): a long word with no spaces wraps instead of
   widening the page at 390 px. */
.fnotes,.fnote,.fsh,.rsvi,.rgh,.fstop,.froute,.kb,.fcard .tchg,.tsum,.tnext{overflow-wrap:anywhere}
.fsh>*,.rgh>*,.kb{min-width:0}
#t-fly h3>span,#t-ev h3>span,.thead .tn{min-width:0;overflow-wrap:anywhere}   /* D156: the journey's label in the events and the title */
.fcard .pill{white-space:normal;overflow-wrap:anywhere;max-width:100%}
.kb.k-flight{border-color:var(--red);color:var(--red)}
/* ===== D107: narrow screens, nothing clipped on the right ============================ */
/* Same breakpoint as the rest of the narrow layout (520 px; D107 asks for <= 480, this is
   a superset). The rows that used to scroll sideways behind a hidden scrollbar (tabs,
   facts, regions, layer switches) now show everything:
   - the tabs: the nav-shell's bottom bar now (G3; the end of this sheet).
   - #facts wraps (two lines at 390 px); #sync keeps its 44 px-wide box and, with
     --sync-pad 7px, a >= 32 px tall one (D77) that now has room since nothing clips it.
   - regions and layer switches wrap (one shared flow), every chip >= 44 px tall on any
     pointer (D48).
   - zoom buttons are 44 px on any pointer (30 px is a mouse size), side by side at the
     bottom right. */
@media (max-width:520px){
  /* padding-block = --sync-pad: the pill's grown box ends exactly at the row's edge */
  .facts{flex-wrap:wrap;overflow:visible;white-space:normal;gap:2px 14px;padding-block:7px;--sync-pad:7px}
  .facts>span{white-space:nowrap}
  body.fit .regions,body.fit .toggles{display:contents}
  .regions button,.toggles button{min-height:44px;min-width:44px}
  body.fit .regions button{padding:0 3px}
  body.fit .toggles button{font-size:.7rem}
  body.fit .toggles button:first-child{margin-left:6px}
  /* +/- side by side at the bottom right (thumb side, where the legend is not drawn here):
     the top of the map stays free, and the controls make one bottom band (scale on the
     left) that fitRouteNarrow() keeps the route out of (NARROW_CTRL_PX). */
  .zoom{top:auto;bottom:12px;flex-direction:row}
  .zoom button{width:44px;height:44px}
  .zoom button+button{border-top:0;border-left:1.5px solid var(--ink)}
  .hint{right:12px}
  /* Ritmo → Tramos (D154; Distancias before): the long values ("Kyōto → Himeji (61 km/h)") wrap at large text sizes. */
  .ledger .r b{white-space:normal;overflow-wrap:anywhere}
}

/* ===== D111: Datos (state, import, prompts) and D113: Pendientes ==================== */
/* D107: seven tabs, eight since D146 (Esenciales). When they do not fit in one row, two rows of four (4 + 4); the grid
   columns follow the tabs' own widths, spread over the row (space-between). */
.datos .tsec:first-child{padding-top:4px}
.dcounts summary,.dpr summary,.dfold summary,.pdadd summary,.pddone summary{cursor:pointer;color:var(--ink2)}
.dcounts .ledger{margin-top:6px}
.dlab{display:flex;flex-direction:column;gap:3px;font-size:.78rem;color:var(--ink2);min-width:0}
.dlab input[type=text],.dlab textarea,.dfields input,.dfields select,.pdf input,.pdf textarea{font:inherit;font-size:.9rem;background:var(--paper);color:var(--ink);border:1px solid var(--hair);border-bottom:1.5px solid var(--ink);padding:6px 8px;min-width:0;width:100%}
.dlab textarea{font-family:var(--mono);font-size:.8rem;resize:vertical;min-height:110px}
.dlab input[type=file]{font:inherit;font-size:.86rem;color:var(--ink);max-width:100%}
.dbar{display:flex;flex-wrap:wrap;gap:8px}
.dbtn{border:1.5px solid var(--ink);padding:6px 16px;font-weight:700;font-size:.88rem}
.dbtn.pri{background:var(--ink);color:var(--paper)}
.dbtn.sec{border-color:var(--hair);color:var(--ink2);font-weight:400}
.dbtn:not(:disabled):hover{background:var(--ink);color:var(--paper)}
.dmsg{font-size:.86rem;min-height:1.2em}
.dmsg.bad{color:var(--red);font-weight:700}
.dmsg.ok{color:var(--dtct);font-weight:700}
.dsum{font-size:.9rem;border-left:3px solid var(--ink);padding:6px 10px;margin-bottom:10px;overflow-wrap:anywhere}
.dsum.bad{border-left-color:var(--red)}
.dfile .small{margin-top:4px}
.dl{margin:6px 0 0;padding-left:18px;font-size:.84rem;display:flex;flex-direction:column;gap:4px}
.dl li small{display:block;color:var(--ink2);font-size:.76rem}
.dl li code{font-family:var(--mono);font-size:.78rem}
.dl.err li::marker{color:var(--red)}
.dfold{margin-top:6px;font-size:.84rem}
.dfold .dl{color:var(--ink2)}
.dpr h4{margin:0;font-size:1rem;letter-spacing:0;text-transform:none;color:var(--ink)}
.pdl{display:flex;flex-direction:column}
.pdi{display:grid;grid-template-columns:28px minmax(0,1fr) auto;gap:2px 10px;align-items:start;padding:7px 0;border-bottom:1px solid var(--hair);font-size:.88rem;overflow-wrap:break-word}
.pdi>div{overflow-wrap:anywhere}
.pdi.own{grid-template-columns:28px minmax(0,1fr) auto 28px}
.pdi>div{min-width:0}
.pdi small{display:block;color:var(--ink2);font-size:.76rem}
.pdi .pdn{white-space:pre-line}
.pdw{font:.76rem var(--mono);color:var(--ink2);text-align:right;white-space:nowrap}
.pdw b{display:block;font:700 .72rem var(--gothic);color:var(--ink)}
.pdi.late .pdw b,.pdi.late .pdw{color:var(--red)}
.pdi.soon .pdw b{color:var(--red)}
.pdi.done b{color:var(--ink2);text-decoration:line-through;text-decoration-color:var(--ink3)}
.pdk{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;margin-top:1px}
.pdk::before{content:"";width:10px;height:10px;border:1.5px solid var(--ink2)}
.pdk.k-cancel::before{border-color:var(--vuelta);background:var(--vuelta)}
.pdk.k-checkin::before{border-color:var(--red);background:var(--red)}
.pdk.k-hotel::before,.pdk.k-leg::before,.pdk.k-booking::before,.pdk.k-flight::before{border-color:var(--ink);background:repeating-linear-gradient(135deg,var(--ink) 0 1.5px,transparent 1.5px 4px)}
.gaps .pdw{white-space:normal}
.gaps .gapgo{min-height:44px;font-size:.78rem}
.ic.mdi{width:1em;height:1em;vertical-align:-.15em;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.mdt{white-space:nowrap}   /* D211: a leg's mode, its icon and label together (core.js modeTag) */
.pdt{font:700 .62rem var(--gothic);letter-spacing:.1em;text-transform:uppercase;color:var(--ink2);margin-right:6px}
.pdi .chk{align-self:start}
.pdi .del{color:var(--ink3);font-size:1.2rem;line-height:1;padding:0 6px}
.pdi .del:hover{color:var(--red)}
.pddone{margin-top:8px;font-size:.84rem}
/* Its own cell under the text (wide) or under the date (narrow: the date is row 2 there). */
.pdok{grid-column:2;margin-top:4px}
.pdok .dbtn{font-size:.8rem;padding:4px 12px}
.pdi.done .pdok .dbtn{color:var(--ink2)}
.pdf{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;margin-top:8px;max-width:72ch}
.pdf #r-todo-title,.pdf textarea,.pdf .tbtn{grid-column:1/-1}
.pdf textarea{resize:vertical}
#t-todo:empty,#t-gaps:empty{display:none}
/* Narrow: the due date goes under the text, so the title keeps the row's width. */
@media (max-width:640px){
  .pdi{grid-template-columns:28px minmax(0,1fr)}
  .pdi.own{grid-template-columns:28px minmax(0,1fr) auto}
  .pdw{grid-column:2;grid-row:2;text-align:left;white-space:normal}
  .pdw b{display:inline;margin-right:6px}
  .pdi .del{grid-column:3;grid-row:1}
  .pdi .pdok{grid-row:3}
}
#t-todo h3 button{letter-spacing:0;text-transform:none;color:var(--red);font-weight:700;font-size:.8rem}
@media (pointer:coarse),(max-width:640px){
  .dbtn,.dlab input[type=text],.dfields input,.dfields select,.pdf input,.pdf .tbtn,#t-todo h3 button,.pdok .dbtn{min-height:44px}
  .dbtn{min-width:44px}
  .dlab input[type=file]{min-height:44px}
  .dcounts summary,.dpr summary,.dfold summary,.pdadd summary,.pddone summary{min-height:44px;display:flex;align-items:center}
  #t-todo h3 button{display:inline-flex;align-items:center}
  .pdi .del{min-width:44px;min-height:44px;margin:-10px -8px -10px 0}
}
/* ===== D125: documents (Datos, the bookings, the image sheet) and D126: calendar ===== */
.dlab select{font:inherit;font-size:.9rem;background:var(--paper);color:var(--ink);border:1px solid var(--hair);border-bottom:1.5px solid var(--ink);padding:6px 8px;min-width:0;width:100%}
.dico{width:34px;height:42px;border:1.5px solid var(--ink);display:flex;align-items:flex-end;justify-content:center;font:500 .58rem var(--mono);letter-spacing:.03em;padding-bottom:4px;position:relative;background:var(--white);color:var(--ink2);margin-top:2px}
.dico::before{content:"";position:absolute;right:-1.5px;top:-1.5px;width:9px;height:9px;background:var(--paper);border-left:1.5px solid var(--ink);border-bottom:1.5px solid var(--ink)}
.dico[data-t="pdf"]{color:var(--red)}
.rsvi .dlinks .maplink{font-size:.78rem}
.dsheet .dbtn{min-height:44px;min-width:44px;display:inline-flex;align-items:center;justify-content:center;text-decoration:none;color:inherit}
.dsheet .dbtn.pri{color:var(--paper)}
a.dbtn.dcal{text-decoration:none;color:inherit;display:inline-flex;align-items:center}
@media (pointer:coarse),(max-width:640px){
  .dlab select,.dopen,.dlinks .maplink{min-height:44px}
}
/* ===== D117/D119: the trip in the masthead, and the Home ============================== */
/* F14: until js/main.js names the view (body[data-view]), no section and no tabs: the trip's
   tabs and facts would flash on the Home or the account screens. visibility, so nothing moves. */
body:not([data-view]) #tabs,body:not([data-view]) .facts,body:not([data-view]) .thdr{visibility:hidden}
/* On the Home and the account screens there is no trip: no tabs, no trip header, no facts row. */
body[data-view="home"] #tabs,body[data-view="home"] .thdr,body[data-view="home"] .facts,body[data-view="home"] #empty,
body[data-view="account"] #tabs,body[data-view="account"] .thdr,body[data-view="account"] .facts,body[data-view="account"] #empty{display:none!important}
.acard{padding-block:4px 18px}
.acard.wide{max-width:none}
.acard h2{margin:0 0 6px;font-size:1.15rem}
.acard .lede{color:var(--ink2);margin:0 0 12px}
.aform{display:flex;flex-direction:column;gap:12px;margin:8px 0}
.aform.row{flex-direction:row;flex-wrap:wrap;align-items:flex-end}
.aform.row .dlab{flex:1 1 220px}
.aform .dlab{display:flex;flex-direction:column;gap:4px}
.aform .dlab>span:first-child{font-size:.8rem;color:var(--ink2)}
.aform input[type=text],.aform input[type=email],.aform input[type=password],.aform select,.acctdlg input{font:inherit;font-size:1rem;background:var(--paper);color:var(--ink);border:1px solid var(--hair);border-bottom:1.5px solid var(--ink);padding:8px;min-width:0;width:100%;min-height:44px}
/* The hidden username of a password-only form (cuenta.js usernameField): the field rule above
   would give it size again; it stays rendered (password managers skip display:none) but 1 px. */
.aform input[data-uname],.acctdlg input[data-uname]{width:1px;height:1px;min-height:0;padding:0;border:0;margin:0}
.acard .dbar{display:flex;flex-wrap:wrap;gap:8px;margin-top:4px}
.acard .dbtn,.acctdlg .dbtn{min-height:44px;display:inline-flex;align-items:center;justify-content:center;text-decoration:none}
a.dbtn.pri{color:var(--paper)}
.alinks .maplink{min-height:44px;display:inline-flex;align-items:center;font-size:.86rem}
.asrow .ic{display:block;flex:none;width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;color:var(--ink2)}
.asrow.soon{color:var(--ink3);cursor:default}
.asrow.soon:active{background:none}
/* E04-3: a help guide (js/views/ayuda.js, js/ayuda-md.js). Titles are .tsec h3, notices .hnote,
   the card .acard: only what a guide has of its own is here (steps, figures, a link in a line).
   Inline links follow C2: inside the app red bold, outside underlined ink. */
.guide>p,.guide li{font-size:.9rem;line-height:1.5}
.guide code{font-family:var(--mono);font-size:.85em}
.guide :is(p,li) a[href^="#"]{color:var(--red);font-weight:700;text-decoration:none}
.guide :is(p,li) a[target]{color:var(--ink);text-underline-offset:2px;text-decoration-color:var(--ink3)}   /* E18-18 (C14): the chip itself is .pill (class="pill atag"); as wide as its text, not the row */
.hnote.ok{border-left-color:var(--dtc);color:var(--dtct)}
.nfoot .maplink{background:none;border:0;padding:0;cursor:pointer;font:inherit;font-weight:700;color:var(--red);font-size:.86rem;min-height:44px}
.acctdlg{border:2px solid var(--ink);background:var(--paper);color:var(--ink);padding:16px;max-width:min(440px,calc(100vw - 32px))}
/* E17-9: a long question (landscape, 402 px high) fits the screen between the safe areas and scrolls inside; ask() opens it at its title. */
dialog.acctdlg:modal{max-height:calc(100vh - 24px);max-height:calc(100dvh - 24px - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px));overflow:auto;overscroll-behavior:contain}
.acctdlg::backdrop{background:var(--scrim,rgba(0,0,0,.4))}   /* E18-18 (C15): the one backdrop (an old ::backdrop that inherits no variable: the fallback) */
.acctdlg h2{margin:0 0 8px;font-size:1.05rem}
.acctdlg .dmsg{margin:0}.acctdlg .dmsg:empty{min-height:0}   /* E18-18: a question without text has no blank band (the alert stays in the tree) */
/* E01-17: the gate of a question (ask({gate})): the word to type, 16 px so iOS does not zoom on focus. */
.acctdlg .dgate span{font-size:.86rem;color:var(--ink)}
.acctdlg .dgate input[type=text]{font-size:1rem;min-height:44px;letter-spacing:.04em}
/* ===== E18-18 (C15, D-c): the close of every sheet and dialog =====
   One chrome everywhere (questions, the .pe sheets, Buscar, Compartir, Feedback, Recomendar,
   the document's image): the --scrim backdrop, a 2 px ink box on paper, 16 px inside, a
   1.05 rem bold title on the left and this "×" on the right, named "Cerrar"
   (js/ui-dialog.js closeX()). The backdrop rule (closes only while nothing was typed; a
   question never) is js/ui-dialog.js typed(). The taxi and medical cards keep their own
   big "Cerrar" (shown to a third person); the shell's bottom sheets (Planificar, Capas),
   their bordered ×. */
.dlgx{display:inline-flex;align-items:center;justify-content:center;flex:none;width:44px;height:44px;margin:-6px -10px -6px auto;padding:0;color:var(--ink2);background:none;border:0;cursor:pointer;-webkit-tap-highlight-color:transparent}
.dlgx:hover{color:var(--ink)}
.dlgx svg{display:block;width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.acctdlgf{display:flex;flex-direction:column;gap:10px}
.acctdlg .dbar{display:flex;flex-wrap:wrap;gap:8px}
/* The password dialogs open with show(), not showModal() (js/softmodal.js: an extension's
   suggestion list outside the dialog must stay clickable): backdrop and centering are ours.
   z-index above the page's own layers (max 46) and far below the extensions' UI. */
.sdlg-bd{position:fixed;inset:0;z-index:90;background:var(--scrim);touch-action:none}
dialog.sdlg{position:fixed;inset:0;z-index:91;margin:auto;width:fit-content;height:fit-content;max-height:calc(100vh - 32px);max-height:calc(100dvh - 32px - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px));overflow:auto;overscroll-behavior:contain}
html.sdlg-on,html.sdlg-on body{overflow:hidden}
/* The session notice (expired, another account's changes), under the facts row. */
.authnote{display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px;border-left:3px solid var(--red);padding:6px 10px;margin:8px 0;font-size:.86rem}
.authnote[hidden]{display:none}
.authnote .dbtn{min-height:44px;display:inline-flex;align-items:center;text-decoration:none}
/* D182: a one-time notice of the account (js/auth.js paintMeNotice): calm, not an error. */
#me-notice[hidden]{display:none}
.menote{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px 14px;border-left:3px solid var(--ink);background:var(--land);padding:8px 10px 8px 12px;margin:8px auto;max-width:var(--maxw);font-size:.9rem}
.menote p{margin:0;flex:1 1 240px}
.menote .dbtn{min-height:44px;min-width:44px;flex:none}
.home{max-width:var(--maxw)}
.hnote{font-size:.86rem;border-left:3px solid var(--ink3);padding:4px 10px;margin:4px 0 12px;color:var(--ink2);overflow-wrap:anywhere}
.hnote.bad{border-left-color:var(--red);color:var(--red)}
.hnote[hidden],.dbar[hidden]{display:none}
.pill.st-ongoing{border-color:var(--redbg);background:var(--redbg);color:#fff}
.pill.st-upcoming{border-color:var(--ink);color:var(--ink)}
.pill.st-past{border-color:var(--ink3);color:var(--ink2)}
.pill.st-none{border-color:var(--hair);color:var(--ink2)}
.hact .dbtn{text-decoration:none;color:inherit;display:inline-flex;align-items:center;justify-content:center;min-height:46px;font-size:.95rem}
.hact .dbtn.pri{flex:1 1 auto;color:var(--paper)}
.dbtn:disabled{opacity:.45;cursor:default}
/* ===== D137: Home v2 (docs/archive/mockups/home-v2/, approved as it is) =====
   The header of the trip in progress or the next one, the cover of each card, the three
   steps, the first-time screen and the page's foot. Colours from the palette only, so both
   themes follow (the dark-only bits repeat for the system's dark mode). */
.hx{color:var(--ink2)}
.htaxi{color:var(--ink);text-decoration-color:var(--red);font-weight:700;display:inline-flex;align-items:center;min-height:44px;align-self:flex-start}
.mdt{fill:var(--paper);stroke:var(--ink2);stroke-width:1.5;vector-effect:non-scaling-stroke}
.hdue h3 a{font-size:.84rem;letter-spacing:0;text-transform:none;color:var(--ink);text-decoration-color:var(--red);font-weight:400;white-space:nowrap;display:inline-flex;align-items:center;min-height:44px}
.hdk{font:500 .66rem var(--mono);color:var(--ink2);border:1.5px solid var(--hair);border-radius:3px;padding:0 5px;white-space:nowrap}
.hhact .dbtn{font-size:1rem;min-height:50px;white-space:nowrap;text-decoration:none;display:inline-flex;align-items:center;justify-content:center}
.hhact .dbtn.pri{flex:0 1 280px;color:var(--paper)}
.hhact .dbtn.sec{flex:0 0 auto;min-width:140px;color:var(--ink);border-color:var(--ink)}
.hhact .dbtn.sec:hover{color:var(--paper)}
.hrec-b:hover{color:var(--paper)}
.htag .pill{background:var(--white)}
.hsteps .dbtn{align-self:flex-start;margin-top:auto;min-height:46px}
.hstart.compact .hsteps .dbtn{grid-column:2;justify-self:start;margin-top:0;min-height:44px;font-size:.84rem;padding:4px 14px}
.hfirst>.wfi{display:block;margin:0 auto;font-size:5rem}
/* The app's foot (#h-foot, a child of body after the views): version and update, this device's
   sync, the landing's links, the copyright. In the column of the views (--maxw); 10 px + the
   Home's 22 px of padding + the Recomendar strip's 8 px = the 40 px it always had above it.
   On every screen of the app (trip-footer, the human 2026-11-01: the Home, each view of a trip,
   every account screen; body.foot-x outside the Home, js/home.js paintFootHost), at every size;
   off the phone's fitted maps (below) and before the first view is up. */
.hpfoot{display:none;width:100%;max-width:var(--maxw);margin:10px auto 0;padding:12px 0 22px;border-top:2px solid var(--ink);flex-wrap:wrap;align-items:center;gap:6px 22px;font-size:.8rem;color:var(--ink2)}
body:is([data-view="home"],.foot-x) .hpfoot{display:flex}
/* Outside the Home there is no trips' sync line: a trip has its own in the header (#sync), an
   account screen none. */
body.foot-x .hsyn{display:none}
/* The phone's fitted maps (Mapa's Ruta, D89, and Interactivo at <= 520 px) fill the window
   between the bars and do not scroll: a foot there would only make the page scroll under the
   map. Their foot is the other views' (one tap away). */
@media (max-width:520px){body.fit .hpfoot,body[data-view="imap"] .hpfoot,body.fit>.hrec,body[data-view="imap"]>.hrec{display:none}}
.hpfoot .wfi{font-size:1.15rem;margin-right:5px;vertical-align:-.25em}
/* The landing's links (site/templates/_footer.html): one group that wraps as a whole; plain
   links of 44 px to tap. The copyright exactly as the human wrote it (no ® or ™). */
.hflinks{display:flex;flex-wrap:wrap;align-items:center;gap:0 18px}
.hflinks a{display:inline-flex;align-items:center;min-height:44px;color:var(--ink);text-underline-offset:3px;text-decoration-color:var(--ink3)}
.hflinks a:hover{text-decoration-color:currentColor}
.hcopy{font-size:inherit;white-space:nowrap}
.hdot{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--ink3);margin-right:6px;vertical-align:.05em}
.hsyn[data-k="ok"] .hdot{background:var(--dtc)}
.hsyn[data-k="pend"] .hdot{background:var(--red)}
.hpfoot .sp{flex:1}
/* F18: version + "Buscar actualización" in one 44 px target; the answer goes on its own line. */
.hupd{display:inline-flex;align-items:center;flex-wrap:wrap;gap:0 10px;min-height:44px;text-align:left;color:var(--ink2)}
.hupd-t{text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--ink3);color:var(--ink)}
.hupd:hover .hupd-t{text-decoration-color:currentColor}
.hupd:disabled{cursor:default;opacity:.7}
.hupd-m{flex-basis:100%;order:9;color:var(--ink);margin-top:-4px}
.hupd-m[hidden]{display:none}
.hupd-m.bad{color:var(--red)}
@media (max-width:520px){
  .hfirst>.wfi{font-size:3.7rem}
  .hpfoot{gap:8px 14px}
  .hpfoot .sp{display:none}
}
/* Long words without spaces (a Latin nameLocal, a free-text status: schema 2.0) wrap
   instead of widening the page: Bases' cards and table, Costos' fare tables, Hoy and the
   place sheet. Kanji already break between any two characters, so Japan looks the same. */
.kj,.side-h h2,.pfacts,.phead .ro,.bcard .hd .ro{overflow-wrap:anywhere}
@media (max-width:980px){.bcard{grid-template-columns:minmax(0,1fr)}}
/* "Hay una versión nueva · Recargar" (data.js, #sw-update) floats over the bottom of the
   page: while it is shown (body.sw-bar, --swbar-h = its height) the page keeps that much
   room below its content, so the last row can scroll out from under it. On the fitted Map
   tab the page does not scroll: the sheet keeps the room instead and the map gives it up,
   so the last row of chips ends above the bar. 14 px is the bar's own offset, 8 px air. */
body.sw-bar{padding-bottom:calc(var(--swbar-h,44px) + 22px + env(safe-area-inset-bottom,0px))}
body.fit.sw-bar{padding-bottom:0}
body.fit.sw-bar .sheet{padding-bottom:calc(var(--swbar-h,44px) + 22px + env(safe-area-inset-bottom,0px))}
/* E01-9: on the phone, in a trip, the notice sits above the tab bar (js/client.js, js/update.js):
   the page's room is the tab bar's plus the notice's (the fab-on rule below adds its own). */
@media (max-width:719px),(max-height:500px){
  body.sw-bar[data-view]:not([data-view="home"]):not([data-view="account"]):not([data-view="wizard"]){padding-bottom:calc(40px + var(--tabbar-h) + var(--swbar-h,44px) + 14px)}
}
/* ===== D127-D130: "Mostrar al taxista" and Esenciales ================================= */
/* The booking editor: the D127 text fields take the whole row (addresses are long). */
.resv label.wide{grid-column:1/-1}
.taxibtn{text-decoration:none;color:inherit;display:inline-flex;align-items:center;justify-content:center;font-size:.84rem;padding:6px 14px}
/* The taxi card: literal black on white (never the theme's tokens), big type, safe areas.
   Portrait: one column, "Cerrar" on top. Landscape on a phone (short and wide): names
   and address on the left, the phrase and the buttons on the right, "Cerrar" in the corner. */
.taxi{position:fixed;inset:0;z-index:45;background:#fff;color:#000;color-scheme:light;overflow:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;
  padding:env(safe-area-inset-top,0px) max(16px,env(safe-area-inset-right,0px)) max(16px,env(safe-area-inset-bottom,0px)) max(16px,env(safe-area-inset-left,0px));font-family:var(--gothic)}
.taxi[hidden]{display:none}
.txtel .num{font-size:clamp(28px,8vw,44px);font-weight:700;line-height:1.2;letter-spacing:.02em;overflow-wrap:anywhere}
.txbtn.pri{background:#000;color:#fff}
/* Hoy's way in: a full-width row under the day title. */
.elink{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;min-height:44px;margin-top:10px;padding:8px 12px;border:1.5px solid var(--ink);background:var(--white);text-align:left;font-size:.9rem;line-height:1.35}
.elink b{color:var(--red)}
.elink .pgo{color:var(--red);font-weight:700;font-size:1.1rem}
.elink:hover{border-color:var(--red)}
.elnk{color:var(--ink);text-decoration-color:var(--red);overflow-wrap:anywhere}
.ephr .ecopy{grid-column:2;grid-row:1/span 3;min-height:44px;min-width:44px;font-size:.82rem;padding:6px 12px}
.ecopy.done{border-color:var(--dtct);color:var(--dtct)}
.ecopy-ta{position:fixed;top:0;left:0;opacity:0;pointer-events:none;width:1px;height:1px}
.efoot .elnk{display:block;padding:5px 0;color:var(--ink2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hmb .dbtn{min-height:40px}
@media (max-width:760px){.dcs .dbtn{flex:1 1 auto;justify-content:center}}
.dcalh{margin-top:8px;max-width:72ch}
/* ===== D135-D138: travellers, split of expenses and Cuentas ========================= */
:root{--amber:#b8730a}
:root[data-theme="dark"]{--amber:#e0a43a}
/* The six categories' colours (ring and its legend): the planner's own hues, one each. */
.c-vuelos{--c:var(--vuelta)}.c-hoteles{--c:var(--red)}.c-transporte{--c:var(--dtc)}.c-comida{--c:var(--amber)}.c-compras{--c:var(--sakura)}.c-otros{--c:var(--ink3)}
.cpaxn[hidden]{display:none}
.accgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,440px),1fr));gap:4px 32px;align-items:start}
.cacc h4{margin:16px 0 6px;font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;color:var(--ink2)}
.eself h4{margin:0 0 2px;font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;color:var(--ink2)}   /* E17-9: offline, why the buttons are off */
/* E17 (D195): a follower (body[data-scope=follower], set by data.js from the server's record
   only) has no Costos, no Documentos (nor the day's photos and wallet, which are documents),
   no expense form and no booking editors: the server sends none of that data and refuses
   those writes (forbidden_scope). What it keeps: Hoy, the map, the bookings' hotel, address,
   times and trains, Esenciales. #v-cost reached by its URL says why it is empty. */
body[data-scope=follower] #tabs [data-view=cost],body[data-scope=follower] #t-qx,body[data-scope=follower] #d-tab-documentos,
body[data-scope=follower] #d-pane-documentos,body[data-scope=follower] #t-diary,body[data-scope=follower] .twal,
body[data-scope=follower] .bedit,body[data-scope=follower] details.tedit[data-fold^="te-"],body[data-scope=follower] .trx,
body[data-scope=follower] [data-actnew],body[data-scope=follower] [data-actedit],body[data-scope=follower] .actdocs,
body[data-scope=follower] [data-hjump=expense],body[data-scope=follower] #v-cost>:not(.vfollow){display:none!important}
.eembf .elnk{display:block;padding:5px 0;color:var(--ink2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pdk.k-passport::before{border-color:var(--dtc);background:var(--dtc);border-radius:50%}
/* D140: the third zoom button (⌂) goes back to the chosen region's frame, or the route's;
   faded while the map already shows that frame. */
.zoom button:disabled{color:var(--ink3);cursor:default}
/* ===== D142: the sub-tabs of Costos, Resumen's big ring, Cuentas' detail per person =====
   The sub-tabs are a row of square chips under the view's top (the selected one inked),
   44 px on touch screens (D48). Resumen: the ring by category at 240 px with its legend on
   the right; narrow, the ring takes the width and the legend goes under it. Cuentas: one
   card per person in a grid (two columns when wide), each with its folds "Qué pagó",
   "Qué le corresponde de otros" and "Transferencias" (+ / − like the Esenciales). */
.ctabs{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 18px}
/* E18-18 (C13): the one sub-tab row: Mapas, Ritmo, Costos, Datos, Esenciales' cards and
   Cuenta's sections (its links: .chip) are these pills. */
.ctabs button,.ctabs .chip{border:1.5px solid var(--hair);border-radius:3px;padding:5px 18px;font-size:.88rem;font-weight:700;color:var(--ink2);background:var(--paper)}
.ctabs .chip{display:inline-flex;align-items:center;justify-content:center;text-decoration:none;min-height:44px}
.ctabs button[hidden],.cpane[hidden]{display:none}
.ctabs button[aria-selected="true"],.ctabs .chip[aria-selected="true"]{border-color:var(--ink);background:var(--ink);color:var(--paper)}
.ctabs button[aria-selected="false"]:hover,.ctabs a.chip[aria-selected="false"]:hover{border-color:var(--ink);color:var(--ink)}
.totsh{margin:20px 0 -8px;font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;color:var(--ink2)}
.tcl{display:flex;flex-wrap:wrap;gap:4px 18px;margin:8px 0 0;font-size:.84rem}
/* trip-footer (the human, 2026-11-01): the Home's "›" links (the card's "cuentas ›", "¿Otro
   viaje?"'s "seguí cargándolo ›") had no rule and showed the browser's blue underline. They are
   the app's "›" links, as Hoy's "cuentas ›" (.tcl a): red, bold, underlined on hover; --red is
   the theme's, so dark mode follows. 44 px to tap: .hacc a below (touch), .hresume a always. */
.hacc a,.hresume a{color:var(--red);font-weight:700;text-decoration:none}
@media (pointer:coarse),(max-width:640px){
  .ctabs button{min-height:44px;min-width:44px}
  /* Inline links: a 44 px box of padding cancelled by margins, the line keeps its height. */
  .tcl a,.hacc a,.hcl{display:inline-block;padding:13px 6px;margin:-13px -6px}
  .tcl{gap:4px 24px;margin-top:14px}
}
/* ===== D145: the destination's local time =========================================
   A chip of its own (line clock icon, as the climate's D91, and the text in the normal
   face, "Ahora en Roma · 15:41 (+5 h)"): right of the dates (#tsub), in the trip header
   under the bar (nav-shell; #tclock-w, the one copy). A tap folds open
   #tclock-p, the time in each country of the trip. Home: the same, small, in the header
   and each card (.hclk). The button is the 44 px target; .tck is the visible chip. */
.tline{display:flex;flex-wrap:wrap;align-items:center;gap:2px 12px;min-width:0}
.tclock{display:inline-flex;align-items:center;max-width:100%;min-width:0;color:var(--ink2)}
.tclock[hidden]{display:none}
.tclock span{font-family:var(--gothic);font-size:.8rem;letter-spacing:0;color:inherit}
/* The destination's time stands out (the human, 2026-11-01): the time and the icon in the
   house accent (as "Faltan N días"), the chip on a faint --redsoft, the rest of the line and
   the border as they were. AA for the time on the chip: 4.8:1 light, 4.9:1 dark. */
.tck{display:inline-flex;align-items:center;gap:6px;min-width:0;padding:1px 10px 1px 7px;border:1px solid var(--hair);border-radius:999px;background:var(--redsoft);line-height:1.5}
.tck-t{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tck-t b{font-weight:600;color:var(--red);font-family:inherit;font-size:inherit;letter-spacing:0}
.clki{flex:none;display:block;color:var(--ink2)}
.tck .clki{color:var(--red)}
.tclock:hover .tck,.tclock[aria-expanded=true] .tck{border-color:var(--ink);color:var(--ink)}
.tzp{max-width:var(--maxw);margin:0 auto;padding:8px 0 10px;border-bottom:1px solid var(--hair)}
.tzp[hidden]{display:none}
.tzl{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,250px),1fr));gap:4px 28px}
.tzl li{display:flex;align-items:baseline;gap:10px;font-size:.86rem;min-width:0}
.tzl .tzn{flex:1 1 auto;min-width:0;overflow-wrap:anywhere}
.tzl .tzn small{color:var(--ink2);margin-left:6px;font-size:.78rem}
.tzl b{font-family:var(--mono);font-weight:500}
.tzl .tzd{font-family:var(--mono);font-size:.76rem;color:var(--ink2);white-space:nowrap;min-width:5.5em;text-align:right}
.tzl li.dev{color:var(--ink2)}
.hclk{display:flex;align-items:center;gap:5px;font-size:.78rem;color:var(--ink2);overflow-wrap:anywhere}
.hclk .clki{width:13px;height:13px;color:var(--red)}
.hclk b{font-weight:600;color:var(--red)}
@media (pointer:coarse),(max-width:640px){
  /* 44 px to tap, the line keeps its height (the padding is cancelled by the margins). */
  .tclock{min-height:44px;margin-block:-10px}
}
/* ===== D147 wide: from 1440 px the views spend the fluid column on more columns ======
   Below 1440 px nothing here applies. Font sizes are the same as on any desktop. */
@media (min-width:1440px){
  /* Mapa: the map box grows with the column at about 1.4:1 (width / height), up to 900 px
     tall (reached from ~1860 px); the line panel is 380 px with its own scroll (it takes
     the row's height, .side contain:size above). cqw: 1 % of .mapcol's width. web/js frames
     "Ruta" again on a resize. */
  .sheet{grid-template-columns:minmax(0,1fr) 380px}

  /* Bases: the table across the column, the cards in a grid of two or three (each card
     one column inside: text, then its map). */
  #base-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,520px),1fr));gap:0 36px;align-items:start}
  #base-list .bcard{grid-template-columns:minmax(0,1fr)}

  /* Running text keeps a readable measure in the wider column. */
  .lede,.qs,.dcalh,.eemg>small,.etip p{max-width:70ch}
}

/* ===== D150: UX review r1 (docs/archive/reports/ux-review-r1.md), batch A ========== */
/* D150 (2), P21: Safari on iOS zooms the page into any field under 16 px when it gets the
   focus. On touch screens every field is 16 px (!important: the components set their own
   smaller sizes with more specific rules). No maximum-scale: pinching stays allowed. */
@media (pointer:coarse){input,select,textarea{font-size:16px!important}}

/* D150 (3), P2: the sync pill shows its state (data.js sets #sync[data-state]): the
   Home's dot (.hdot) before the text, green when synced, amber with --ink text for
   changes waiting, grey with --ink text offline, red (dot and text, with the time of the
   last good round) on error; hollow while a round runs. 44 px tall on touch screens. */
.facts .sync{display:inline-flex;align-items:center;gap:6px;color:var(--ink2)}
.facts .sync::before{content:"";flex:none;width:8px;height:8px;border-radius:50%;background:var(--ink3)}
.facts .sync[data-state="ok"]::before{background:var(--dtc)}
.facts .sync[data-state="pending"]{color:var(--ink)}
.facts .sync[data-state="pending"]::before{background:var(--amber)}
.facts .sync[data-state="offline"]{color:var(--ink)}
.facts .sync[data-state="error"]{color:var(--red)}
.facts .sync[data-state="error"]::before{background:var(--red)}
/* IAM E1.3: no usable session; nothing is lost (the notice under the facts says what to do). */
.facts .sync[data-state="auth"]{color:var(--red)}
.facts .sync[data-state="auth"]::before{background:none;box-shadow:inset 0 0 0 1.5px var(--red)}
.facts .sync[data-state="syncing"]::before{background:none;box-shadow:inset 0 0 0 1.5px var(--ink3)}
/* D175: the API refuses this release's writes until it is updated (js/client.js shows the
   notice with Actualizar); nothing is lost, so amber like changes waiting, not red. */
.facts .sync[data-state="outdated"]{color:var(--ink)}
.facts .sync[data-state="outdated"]::before{background:none;box-shadow:inset 0 0 0 2px var(--amber)}
/* 44 px on touch screens without moving the row (Mapa frames the route on the height left):
   data.js pads the pill by --sync-pad above and below and gives it back with equal negative
   margins, so 12.5 px each side makes the box 44.8 px tall and the line keeps its height. */
@media (pointer:coarse){.facts{--sync-pad:12.5px}.facts .sync{min-height:44px}}
@media (max-width:520px){.facts>.sync{white-space:normal}}

/* D150 (4), P3/P8/P26: Hoy's links to Costos in the app's link style (red, as "ver todos ›");
   Datos' file pickers are a .dbtn under the invisible native input, which keeps the taps,
   the focus (shown on the button) and the files. */
.tcl a{color:var(--red);font-weight:700;text-decoration:none}
.tcl a:hover{text-decoration:underline}
.dfpick{position:relative;display:inline-flex}
.dfin{position:absolute;inset:0;width:100%;height:100%;margin:0;padding:0;opacity:0;cursor:pointer;font-size:0}
.dfin:not(:disabled):hover+.dbtn{background:var(--ink);color:var(--paper)}
.dfile .dbtn{display:inline-flex;align-items:center;justify-content:center;color:var(--ink)}
.dfpick:focus-within .dbtn{outline:2px solid var(--red);outline-offset:2px}
.dfin:disabled+.dbtn{opacity:.45;cursor:default;pointer-events:none}
.bedit{margin-top:8px}
/* Review 2026-10-23: "desayuno" is a green outline chip (the "pagado" family, D150 --dtct token); the
   confirmation is labelled, smaller, and a long code wraps instead of widening the line. */
.pill.bkf{background:none;border-color:var(--dtct);color:var(--dtct)}
.bconf .mono{font-size:.78rem;overflow-wrap:anywhere}
/* D158: the check-in code and the booking's instructions (Bases → Tu reserva, Hoy → Dónde
   duermo). Long instructions show their first line and fold the rest ("ver instrucciones ▸"). */
.ckchip{display:inline-block;max-width:100%;border:1px solid var(--ink);padding:0 6px;font-size:.82rem;line-height:1.5;overflow-wrap:anywhere}
.bnotes{margin:6px 0 0;font-size:.84rem;color:var(--ink2);white-space:pre-line;overflow-wrap:anywhere}
.bnfold{white-space:normal}
.bnfold .bn1{margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bnfold:has(>details[open])>.bn1{display:none}
.bnfold>.tedit{margin-top:2px}
.bnfull{margin:0;white-space:pre-line}
.resv textarea{font:inherit;background:var(--paper);color:var(--ink);border:1px solid var(--hair);border-bottom:1.5px solid var(--ink);padding:6px 8px;min-width:0;width:100%;resize:vertical;field-sizing:content;min-height:5.2em;max-height:18em}
@media (max-width:520px){
  .book{min-width:0;display:block;font-size:.86rem}
  .book thead{display:none}
  .book tbody{display:block}
  .book tr{display:grid;grid-template-columns:max-content max-content minmax(0,1fr) auto auto;
    grid-template-areas:"base base base prio bk" "ci co n n n" "h h h h h" "z z z z go";gap:6px 8px;align-items:center;padding:10px 0;border-bottom:1px solid var(--hair)}
  .book td{display:block;padding:0;border:0;min-width:0}
  .book tr.done{background:var(--redsoft)}
  .book tr.done td{background:none}
  .book td:nth-child(1){grid-area:base;overflow-wrap:anywhere}
  .book td:nth-child(2){grid-area:ci}
  .book td:nth-child(3){grid-area:co}
  .book td:nth-child(4){grid-area:n}
  .book td:nth-child(5){grid-area:z;font-size:.8rem;color:var(--ink2)}
  .book td:nth-child(6){grid-area:prio;justify-self:end}
  .book td:nth-child(7){grid-area:bk;justify-self:end}
  .book td:nth-child(8){grid-area:h}
  .book td:nth-child(9){grid-area:go;justify-self:end}
  .book td.bn::before{content:"· "}
  .book input[type=text]{min-width:0}
}
/* mobile-qa 2026-11-02: no cell narrower than the longest label («Presupuesto», «Alternativas»,
   «Documentos»: 5.7rem of bold .8rem text, plus the 15 px of padding and border). The floor is
   in rem, so it grows with the text size: at 125-150 % three cells no longer fit and the row
   is two to a row, at 200 % one, still of one width, instead of a label running out of its
   cell and the page scrolling sideways. At 100 % on a 375 px phone three still fit. */
@media (max-width:520px){
  .ctabs{--ctab-min:calc(5.9rem + 15px);display:grid;grid-template-columns:repeat(auto-fill,minmax(max(calc((100% - 13px) / 3),var(--ctab-min)),1fr));gap:6px}
  .ctabs:not(:has(>:not([hidden])~:not([hidden])~:not([hidden]))),
  .ctabs:has(>:not([hidden])~:not([hidden])~:not([hidden])~:not([hidden])):not(:has(>:not([hidden])~:not([hidden])~:not([hidden])~:not([hidden])~:not([hidden]))){grid-template-columns:repeat(auto-fill,minmax(max(calc((100% - 7px) / 2),var(--ctab-min)),1fr))}
  .ctabs button{padding:5px 6px;font-size:.8rem}
}
/* D150 (7): the fold's own arrow (the native marker is lost with display:inline-flex on touch). */
.tedit>summary{list-style:none}
.tedit>summary::-webkit-details-marker{display:none}
.tedit>summary::after{content:"▸";color:var(--red);margin-left:.35em}
.tedit[open]>summary::after{content:"▾"}
.csum .cimain .cbudno a{color:var(--red);font-weight:700;text-decoration:none}
#c-fares .fare+.fare{margin-top:18px}
.tfix{position:relative;display:block;min-width:0}
.tfpre{position:absolute;left:8px;top:50%;transform:translateY(-50%);font-family:var(--mono);font-size:.9rem;color:var(--ink2);pointer-events:none}
.csum .ctr a{color:var(--red);font-weight:700;text-decoration:none;margin-left:6px}
.estay .eaddr.miss{color:var(--red);font-weight:700}

/* ===== D152/D159: Bases, the zone map of each stay and the cards' layout ===============
   D159: the zone map is a vector drawing (js/vector-map.js zoneMap()) in the route map's style, all
   in the theme's tokens: the map's land (--land) as its paper, parks (--park) and water
   (--sea) as faint tints derived from the theme, main roads barely there, rails as the
   route map's (a grey line with a paper dash inside), stations as its white squares,
   labels with a --land halo (paint-order: stroke). The OSM credit sits small at the map's
   bottom right, over it. Under the map: the hotel's walking distances (.bdist), the
   attractions and the legend. */
:root{--park:color-mix(in srgb,var(--land) 84%,var(--dtc));--sea:color-mix(in srgb,var(--land) 78%,var(--vuelta))}
.bmap{position:relative;overflow:hidden}
.zmap .zbg{fill:var(--land)}
.zmap .zpark{fill:var(--park)}
.zmap .zwater{fill:var(--sea)}
.zmap .zriver{fill:none;stroke:var(--sea);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.zmap .zroad{fill:none;stroke:var(--ink3);stroke-linecap:round;stroke-linejoin:round}
.zmap .zroad.zmaj{stroke-width:1.7;opacity:.6}
.zmap .zroad.zmin{stroke-width:1.1;opacity:.35}
.zmap .zrail path{fill:none;stroke-linejoin:round}
.zmap .zrail-o{stroke:var(--ink2);stroke-width:3;stroke-linecap:round}
.zmap .zrail-i{stroke:var(--paper);stroke-width:1.3;stroke-dasharray:4 4}
.zmap .zr-subway .zrail-o{opacity:.72}
.zmap .zr-tram .zrail-o{stroke-width:1.8;opacity:.72}
.zmap .zr-tram .zrail-i{stroke-width:.7;stroke-dasharray:2.5 2.5}
.zmap .zst{fill:var(--white);stroke:var(--ink);stroke-width:1.5}
.zmap .zlab{font-family:var(--gothic);font-weight:700;fill:var(--ink);paint-order:stroke;stroke:var(--land);stroke-width:3;stroke-linejoin:round}
.zmap .zwalk{stroke:var(--red);stroke-width:1.4;stroke-dasharray:3 3;stroke-linecap:round}
.zmap .zwalkt{fill:var(--red)}
.zmap .zring{fill:none;stroke:var(--hotel);stroke-width:1.2;stroke-dasharray:4 3}
.zmap .zzone{fill:var(--hotel)}
.zmap .zat circle{fill:var(--red);stroke:var(--white);stroke-width:1.2}
.zmap .zat text{font-family:var(--mono);fill:#fff}
.zmap .zat.done circle{fill:var(--white);stroke:var(--ink3)}
.zmap .zat.done text{fill:var(--ink3)}
.zmap .zscale line{stroke:var(--ink);stroke-width:2}
.zmap .zscale text{font-family:var(--mono);fill:var(--ink2);paint-order:stroke;stroke:var(--land);stroke-width:3}
.bmap-attr{position:absolute;right:0;bottom:0;padding:1px 5px;font:500 .62rem/1.3 var(--gothic);color:var(--ink);
  background:color-mix(in srgb,var(--paper) 82%,transparent);pointer-events:none;white-space:nowrap}
/* D152 (e): the stay's typical climate, Hoy's look (glyph + --ink2 text), under the title. */
.bclim{display:flex;align-items:center;gap:6px;margin:6px 0 0;font-size:.84rem;color:var(--ink2)}
.bclim .cwx{margin-block:-3px}
.bcard .bdist{list-style:none;margin:8px 0 0;padding:0;font-size:.82rem;display:grid;gap:2px}
.bcard .bdist li{overflow-wrap:anywhere}
/* D152 (d): from 720 px each card is two columns, the text on the left and the map on the
   right (a 4:3 box at the top of its column, never wider than the card); below, D150 (7)
   (text, then the map). 720 px, not 521 (review of 2026-11-02 at ~675 px): between them
   the text column got narrower than on a 375 px phone (~280-320 px; the dates and the
   climate line broke in two); 720 is also where the shell stops being a phone (shell.js
   PHONE_MQ). The definition list keeps its two columns from 521 px. From 900 px the cards sit in a grid of at most two
   columns: two once each card gets 680 px (a ~1600 px window, D159: the neighbourhood
   map needs its ~440 px), one below; never three. The cards of a row share its height
   (align-items:stretch), their content at the top. */
@media (min-width:521px){.bcard dl{grid-template-columns:max-content minmax(0,1fr)}}
@media (min-width:720px){
  .bcard,#base-list .bcard{grid-template-columns:minmax(0,1fr) minmax(0,min(440px,46%));gap:16px 28px;align-items:start}
  .bmapc{min-width:0}
}
@media (min-width:900px){
  #base-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(max(680px,calc((100% - 40px) / 2)),1fr));gap:0 40px;align-items:stretch}  /* D159: 680 px per card so the neighbourhood map keeps ~440 px (two columns from ~1600 px) */
}
/* D152 (b): the zone picture is a link to Google Maps (a new tab): the whole box, a pointer,
   a small hint at its top right (over the picture, like the OSM credit at the bottom) and a
   visible focus ring for the keyboard. */
.bmapa{display:block;width:100%;height:100%;color:inherit;cursor:pointer}
.bmapa:focus-visible{outline:2px solid var(--red);outline-offset:-2px}
.bmap-go{position:absolute;right:0;top:0;padding:1px 5px;font:700 .62rem/1.3 var(--gothic);color:var(--ink);
  background:color-mix(in srgb,var(--paper) 82%,transparent);pointer-events:none;white-space:nowrap}
/* F2: a card the one interactive map never visited (js/imap-base.js paintHint): the same
   corner says how to bring it, instead of "Abrir en Google Maps" (the first tap or click
   brings the map; offline the hint goes and the link is back). */
.bmap-hint{position:absolute;right:0;top:0;z-index:1;padding:1px 5px;font:700 .62rem/1.3 var(--gothic);color:var(--ink);
  background:color-mix(in srgb,var(--paper) 82%,transparent);pointer-events:none;white-space:nowrap}

/* ===== D155: Lugares (#v-places) and the ways into a place's sheet ==================
   One card per place in route order: one column on a phone, two from 900 px. A card is a
   button (44 px and more) with the names, the type, the dates, the climate line of Bases
   (.bclim, D152 (e)) and what was visited; a red › at its right. */
.plc-h .kj{font-size:1.6rem;line-height:1.1;overflow-wrap:anywhere}
.plc-h .plc-hoy{background:var(--red);border-color:var(--red);color:#fff}
.bcard .hd .bpl{display:inline-flex;align-items:baseline;flex-wrap:wrap;gap:2px 12px}
@media (pointer:coarse),(max-width:640px){
  .tfic,.pstep{display:inline-flex;align-items:center;min-height:44px}
}

/* ===== Tester d148-d161 B12 (WebKit on macOS; to check on the iPhone) ================= */
/* Every <select> is drawn by the page, not by the platform: a native one in WebKit ignores
   min-height (21 px tall on macOS). The chevron is two CSS gradients in currentColor (the
   CSP allows no data: images), so the dark theme needs nothing. The specificity (0,1,2)
   wins over the components' ".x select" rules only for what is set here: their background
   colour, border, padding and font stay theirs. Touch screens: 44 px. */
html select:not([multiple]){-webkit-appearance:none;appearance:none;border-radius:0;padding-right:26px;
  background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-position:calc(100% - 14px) 50%,calc(100% - 9px) 50%;background-size:5px 5px,5px 5px;background-repeat:no-repeat}
@media (pointer:coarse){html select:not([multiple]){min-height:44px}}
/* Number fields without the spinner (WebKit puts it inside the field and the fixed-width
   fare inputs of Presupuesto pushed the table 21 px past a 375 px screen); the keyboard and
   the arrow keys still step the value. */
input[type=number]{-moz-appearance:textfield;appearance:textfield}
input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;appearance:none;margin:0}
/* ===== D163 (b): the forecast in the climate widgets (js/climate.js fcRow / fcLine) ===== */
.cfcl{font-family:var(--gothic);font-size:.68rem;color:var(--ink2);line-height:1.4;letter-spacing:.02em}
.ctag{font-variant-caps:all-small-caps;letter-spacing:.08em;font-weight:700;color:var(--ink)}
.ctag.typ{font-weight:400;color:var(--ink2)}
.bclim.bfc span{color:var(--ink)}

/* ===== D163 (c): the pre-trip checklist button of Ritmo → Pendientes ===== */

/* ===== D163 (d): the spending pace (Costos → Resumen, Hoy) ===== */

/* ===== D163 (e): the search (js/search.js) ===== */
.srch-btn[hidden]{display:none!important}
.srch{position:fixed;inset:0;z-index:45;background:var(--scrim);display:flex;justify-content:center;align-items:flex-start;
  padding:max(12px,env(safe-area-inset-top,0px)) max(12px,env(safe-area-inset-right,0px)) max(12px,env(safe-area-inset-bottom,0px)) max(12px,env(safe-area-inset-left,0px))}
.srch[hidden]{display:none}
body.srch-on{overflow:hidden}
.srbox{background:var(--paper);color:var(--ink);border:2px solid var(--ink);width:min(640px,100%);max-height:100%;display:flex;flex-direction:column;padding:16px 16px 8px;min-width:0}
.srbar{display:flex;align-items:center;justify-content:space-between;gap:12px}
.srt{font-size:1.05rem;margin:0}
.srbar .dbtn{min-height:44px}
.srq{font:inherit;font-size:16px;margin-top:10px;background:var(--paper);color:var(--ink);border:1px solid var(--hair);border-bottom:2px solid var(--ink);padding:10px;width:100%;min-height:44px}
.srst{margin:6px 0 2px;font-size:.78rem;color:var(--ink2);min-height:1.1em}
.srl{overflow-y:auto;-webkit-overflow-scrolling:touch;min-height:0;overscroll-behavior:contain}
.srg+.srg{margin-top:6px}
.srgh{font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;color:var(--ink2);margin:8px 0 2px;font-weight:700}
.sri{display:flex;align-items:center;gap:10px;min-height:44px;padding:6px 8px;border-bottom:1px solid var(--hair);cursor:pointer}
.sri[aria-selected="true"]{background:var(--redsoft);box-shadow:inset 3px 0 0 var(--red)}
.srb{display:flex;flex-direction:column;min-width:0;flex:1}
.srb b{font-weight:700;overflow-wrap:anywhere}
.srb small{font-size:.78rem;color:var(--ink2);overflow-wrap:anywhere}
.sro{flex:none;font-size:.74rem;color:var(--red);font-weight:700}
.srmore{font-size:.74rem;color:var(--ink2);margin:4px 8px}
.srhit{outline:3px solid var(--red);outline-offset:3px;transition:outline-color .4s}

/* ===== D164: "Agregar al itinerario" and "Editar" (js/plan-edit.js) =====
   The entry points (Ritmo's unfolded day, the place sheet) and the sheet, an overlay like
   the search's: the views keep only a button (D149). */
.peadd{font-size:.84rem}
.peoff[hidden]{display:none}
.peed{flex:none;align-self:start;font-size:.76rem;font-weight:700;color:var(--red);border:1.5px solid var(--hair);padding:2px 10px;min-height:28px}
body.pe-on{overflow:hidden}
.pebox{background:var(--paper);color:var(--ink);border:2px solid var(--ink);width:min(560px,100%);max-height:100%;display:flex;flex-direction:column;padding:16px;min-width:0}
.pebox .srbar{flex:none}
.pebody{overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;min-height:0;display:flex;flex-direction:column;gap:10px;padding-top:10px}
.pebody .dlab input,.pebody .dlab textarea,.pebody .pesel{font:inherit;font-size:16px;background:var(--paper);color:var(--ink);border:1px solid var(--hair);border-bottom:1.5px solid var(--ink);padding:8px;min-width:0;width:100%;min-height:44px}
.pebody .dlab textarea{font-family:inherit;min-height:64px;resize:vertical}
.pebody .dbtn{min-height:44px;min-width:44px}
.pebody .dmsg{margin:0}
.pechk{display:flex;align-items:center;gap:8px;min-height:44px;font-size:.88rem;cursor:pointer}
.pechk input{width:20px;height:20px;flex:none;accent-color:var(--red)}
@media (max-height:500px){.pebox{padding:10px 16px}.pebody{padding-top:6px}}
.telinkoff[hidden]{display:none}
.tequick .dbtn{font-size:.8rem;padding:4px 10px}
.telegs .dbtn{align-self:flex-start}

/* ===== D165: Ritmo → Entradas and its sheet (js/views/entradas.js), Hoy's activities and
   wallet (js/views/hoy.js, js/wallet.js) and Preparar para el viaje (js/prepare.js); the
   server's state is the admin panel's (web/admin/index.html has its .srvbad/.srvno) ===== */
.achips{display:flex;flex-wrap:wrap;gap:4px;margin-top:2px}
.achips:empty{display:none}
.achips .pill{white-space:normal;overflow-wrap:anywhere;max-width:100%}
.pill.acx{border-color:var(--vuelta);color:var(--ink)}
.actbar{flex-wrap:wrap}
.pdk.k-payment::before{border-color:var(--red)}
.pdk.k-ticket::before{border-color:var(--red);border-radius:50%}

/* ===== D163 (f): the diary (js/diary.js) and the printable summary (js/views/resumen.js) ===== */
.tdiary summary .dyn{color:var(--ink2)}
.dyg{display:grid;grid-template-columns:repeat(auto-fill,minmax(88px,1fr));gap:6px;margin-top:8px}
.dyg .dyno{grid-column:1/-1;margin:0}
.dyt{position:relative;display:block;aspect-ratio:1;min-height:44px;background:var(--land);border:1px solid var(--hair);overflow:hidden}
.dyt img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.dyt img[hidden]{display:none}
.dyph{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:.7rem;color:var(--ink2)}
.dyph[hidden]{display:none}
.dybar{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
.dybar .dbtn{min-height:44px}
.tdiary .dmsg{margin:6px 0 0}
.dynotes{white-space:pre-wrap;overflow-wrap:anywhere;margin:6px 0 0;font-size:.86rem}
.dyedit{margin-top:4px}
/* ===== D166 (2): booked trains (js/trains.js): the lines under a leg, Ritmo → Tramos' list
   and its editor (a row per train, 16 px fields so iOS does not zoom), Hoy's "Próximo". */
.ltrl{display:block;margin-top:2px}
.ltrl>span{display:block}
.ctrl{font-size:.74rem;color:var(--ink2);margin-top:4px}
.trrow{border-top:1px solid var(--hair);padding:8px 0}
.trh{margin:0;display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 8px;font-size:.9rem}
.trd{color:var(--ink2);font-size:.8rem}
.trl{margin:2px 0 0;font-size:.84rem;overflow-wrap:anywhere}
.trx{margin-top:2px}
.trdt{margin-top:12px}
.trdt>summary{font-weight:700;color:var(--ink)}
.ltrs{display:flex;flex-direction:column;gap:8px;margin-top:8px}
.ltrow{border:1px solid var(--hair);padding:6px 10px 10px;margin:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px 10px;min-width:0}
.ltrow legend{font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;color:var(--ink2);padding:0 4px}
.ltrow label{display:flex;flex-direction:column;gap:2px;font-size:.76rem;color:var(--ink2);min-width:0}
.ltrow .ltw{grid-column:1/-1}
.ltrow input{font:inherit;font-size:16px;background:var(--paper);color:var(--ink);border:1px solid var(--hair);border-bottom:1.5px solid var(--ink);padding:6px 8px;min-width:0;width:100%;min-height:44px}
.ltrow .ltdel{grid-column:1/-1;justify-self:start;min-height:44px}
.lterr{grid-column:1/-1;margin:0;color:var(--red);font-size:.78rem}
.ltadd{align-self:flex-start;min-height:44px}
.lthelp{margin:0}
@media (min-width:640px){.ltrow{grid-template-columns:repeat(4,minmax(0,1fr))}.ltrow .ltw{grid-column:span 2}}
/* ===== D166 (3): the medical sheet (js/medical.js): its section in Esenciales, the editor
   (#med, a .pe sheet) and the card (#medc, the taxi card's black on white, D128). */
.medfs{border:1px solid var(--hair);padding:8px 12px 10px;margin:0;display:flex;flex-direction:column;gap:6px;min-width:0}
.medfs legend{font-weight:700;font-size:.86rem;padding:0 4px}
.mo{margin:6px 0 0;font-size:20px;line-height:1.4;white-space:pre-wrap;overflow-wrap:anywhere}
/* Print: only the summary, in light colours, a day never split (D163 (f)). */
@media print{
  :root:not([data-print]),:root[data-theme]{--paper:#fff;--ink:#111;--ink2:#444;--ink3:#555;--hair:#ccc;--land:#f2f2ef;--red:#c8102e;--white:#fff;--ida:#c8102e;--vuelta:#2b4c9b;--dtc:#2f8a5a;--redsoft:transparent;color-scheme:light}
  @page{margin:14mm}
  html,body{background:#fff}
  body[data-view="summary"]>:not(main),body[data-view="summary"]>main>:not(#v-summary){display:none!important}
}

/* ===== D171: Mapa → Ruta · Interactivo (js/imap.js) ===================================
   The two maps' sub-tabs (Ritmo's chips) over both map views. The interactive map: the
   filters above it (the day's select and the kinds' switches, the route map's .tg), the
   box filling the window below the header on a phone (js/imap.js fitBox(); the page does
   not scroll there, as D89's map), the zoom pair in the route map's bordered style, the
   message line, and the pin's card and the saved zones as a sheet over the map's bottom.
   Touch targets 44 px on coarse pointers; the tiles' credit small at the bottom right. */
.mtabs{display:none;max-width:var(--maxw);margin:8px auto}
body[data-view="map"] .mtabs,body[data-view="imap"] .mtabs{display:flex}
.mtabs button{padding:3px 16px}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
/* D171 (round 2): the place sheet's map (js/imap-place.js): the interactive map over D160's
   drawing, which stays under it (hidden, inert) as the fallback; the same 4:3 box. The
   drawing's legend line ("▫ estación") only while the drawing is what shows. */
.pm-wrap{position:relative}   /* the size too: MapLibre's .maplibregl-map sets position:relative */
.pmap.gl .pm-box{visibility:hidden}
.pmap.gl .pm-key,.pmap.gl .pm-cap{display:none}
.pm-key{display:inline-flex;align-items:center;gap:4px;color:var(--ink2)}
.pm-key[hidden]{display:none}
@media (max-width:520px){
  body[data-view="map"] .mtabs,body[data-view="imap"] .mtabs{display:none}   /* under the map switch */
  body[data-view="imap"]{padding-bottom:0}
}
/* D208: a trip without a hand-made map package has the interactive map alone (js/nav.js
   mapView() sets body[data-noroute]): no Ruta · Interactivo switch, and on a phone the
   map's chips and message line take its place at the top of the box. */
body[data-noroute] .mtabs,body[data-noroute] .mtabs-o{display:none!important}
.imlegk-back{border-top-color:var(--vuelta)}
.imlegk-dt{border-top:3px dotted var(--dtc)}   /* D214: an invitation, not a warning */
/* 2026-10-31, no sideways scroll on a phone: both maps' layer switches behind "Capas".
   The bar's row ran past the screen's edge at 390 px (the day's select next to six switches),
   and a bar that scrolls sideways reads as the page moving. On the shell's phone layout
   (js/shell.js PHONE_MQ: portrait, and landscape by height) the day's select takes the row
   with a "Capas" button (.mlayers) at its end; the switches are rows of a bottom sheet
   (.lsheet, js/layers.js) drawn as the Planificar sheet (#tg-plan): over the tab bar, a top
   rule, the shadow, a title and the close button, 44 px+ rows, each a checkbox with the
   layer's mark on the map. The legend in the route map (.key) is not drawn on a phone: its
   switches are the sheet's, its two plain marks the sheet's foot (.lkey). Wider, nothing
   changes: the sheet is display:contents, so the switches stay in the bar. */
.ctl.mlayers,.lsh,.lkey,.lsym{display:none}
.mlayers .ic,.lsheet .ic{display:block;flex:none;width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
@media (max-width:719px),(max-height:500px){
  .key{display:none}
  .ctl.mlayers{display:inline-flex;border-color:var(--ink);color:var(--ink);font-size:.8rem}
  .ctl.mlayers[aria-expanded="true"]{color:var(--paper)}
  :is(#lsheet-map,#lsheet-imap).open :is(#toggles,#im-kinds){display:flex;flex-direction:column;flex-wrap:nowrap;align-items:stretch;gap:0;
    margin:0;padding:0;overflow:visible;white-space:normal}
  :is(#lsheet-map,#lsheet-imap).open .tg{display:flex;align-items:center;gap:12px;width:100%;min-height:48px;margin:0;padding:0 16px;
    font-size:1rem;color:var(--ink);text-align:left}
  /* the switch's square as a checkbox: an empty box off, filled with a check on */
  :is(#lsheet-map,#lsheet-imap).open .tg::before{display:block;flex:none;width:20px;height:20px;box-sizing:border-box;border:2px solid var(--ink2);background:none}
  :is(#lsheet-map,#lsheet-imap).open .tg[aria-pressed="true"]::before{border-color:var(--ink);background:var(--ink)}
  :is(#lsheet-map,#lsheet-imap).open .tg{position:relative}
  :is(#lsheet-map,#lsheet-imap).open .tg[aria-pressed="true"]::after{content:"";position:absolute;left:23px;top:50%;width:6px;height:11px;
    border:solid var(--paper);border-width:0 2.5px 2.5px 0;transform:translate(0,-62%) rotate(45deg)}
  :is(#lsheet-map,#lsheet-imap).open .tg[aria-pressed="false"]{color:var(--ink2)}
  :is(#lsheet-map,#lsheet-imap).open .tg span{text-decoration:none}
}
/* Landscape phone: the rows in columns, so the whole sheet fits the short window. */
@media (max-height:500px){
  :is(#lsheet-map,#lsheet-imap).open :is(#toggles,#im-kinds){display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}
}
/* ===== F3: "Nuevo viaje", steps 2 and 3 (#v-wizard, js/views/cargar.js) =====
   One step on screen at a time (phone first): the steps bar, then the pane. */
/* A focused page, like the summary: no tabs (before an itinerary they lead nowhere) and no facts row; "‹" goes back to Viajes. */
body[data-view="wizard"] #empty,body[data-view="wizard"] #tabs,body[data-view="wizard"] .thdr,body[data-view="wizard"] .facts{display:none}
.wiz{max-width:680px;margin-inline:auto}
.wiz h2{margin:4px 0 6px;font-size:1.4rem;line-height:1.25;text-wrap:balance}
.wfacts{list-style:none;margin:0 0 12px;padding:0;border-top:1px solid var(--hair)}
.wfacts li{display:grid;grid-template-columns:7.5em minmax(0,1fr);gap:10px;padding:8px 0;border-bottom:1px solid var(--hair);font-size:.9rem}
.wfacts li span{color:var(--ink2)}
.wfacts li b{font-weight:500;overflow-wrap:anywhere}
.wfacts li.miss b{color:var(--ink2);font-weight:400;font-style:italic}
.wzbig{min-height:52px;font-size:1rem;padding:8px 22px}
.wcopy{display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px;margin:6px 0 14px}
.wcopy .wzbig{flex:1 1 220px}
.wsay{margin:0 0 14px;padding-left:1.4em;font-size:.95rem;line-height:1.5}
.wsay li+li{margin-top:6px}
.wnav{margin-top:18px;padding-top:14px;border-top:1px solid var(--hair)}
.wdrop{border:1.5px dashed var(--hair);padding:12px;margin-bottom:12px;display:grid;gap:10px}
.wdrop.over{border-color:var(--ink);background:var(--land)}
.wdrop textarea{min-height:180px}
.wfile{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px}
.wfile .dbtn{display:inline-flex;align-items:center;justify-content:center;color:var(--ink)}
.wres{margin-top:12px;border:1.5px solid var(--ink);padding:14px}
.wres.bad{border-color:var(--red)}
.wrap .wres h3,.wrap .hpaths .hph{display:block;margin:0 0 6px;padding:0;border:0;font-size:1.1rem;line-height:1.3;letter-spacing:0;text-transform:none;color:var(--ink);text-align:left}
.wres p{margin:0 0 10px;font-size:.92rem;line-height:1.5}
.wres .dl{margin:0 0 10px;padding-left:18px;font-size:.88rem}
.wres .dl li+li{margin-top:4px}
.wres .dl small{display:block;color:var(--ink2);font-family:var(--mono);font-size:.74rem;overflow-wrap:anywhere}
.wres .wzbig{width:100%}
.drev.dmiss .wcopy .wzbig{flex-basis:100%;max-width:520px}   /* full width (to 520 px); "Copiado" goes under it */
@media (pointer:coarse),(max-width:640px){.wres .dfold>summary,.drev.dmiss .dfold>summary{min-height:44px;padding:11px 0;box-sizing:border-box}}
#empty-go{margin:-24px auto 40px;max-width:60ch;text-align:center;font-size:.95rem;color:var(--ink2)}
#empty-go p{margin:0 0 12px}
#empty-go ul{text-align:left;margin:0 auto 14px;padding-left:1.2em;max-width:52ch;line-height:1.5}
#empty-go a:not(.dbtn){color:var(--ink)}
#empty-go .quiet{font-size:.88rem}
/* D214: a trip with no itinerary yet opens its map; on it the map's own short line (js/imap.js
   paintInvite) says what the notice says elsewhere. */
body[data-imnoplan][data-view="imap"] #empty,body[data-imnoplan][data-view="imap"] #empty-go{display:none}
#empty-go .quiet a{display:inline-flex;align-items:center;min-height:44px}
#empty-go[hidden],body[data-view="home"] #empty-go,body[data-view="account"] #empty-go,body[data-view="wizard"] #empty-go{display:none}
/* ===== nav-shell (feedback 2026-10-31, G1-G6, G10-G12; option A of docs/design/nav-shell/) =====
   One bar on every screen: the landing's lockup, a pipe, the breadcrumb and the controls;
   in a trip the tabs under it (wide) or a bottom tab bar (phone: <= 719 px wide, or a
   landscape phone by its height). Metrics: --bar-h the bar's row, --tabbar-h what the
   bottom tab bar takes (0 on wide; the map's fit and the page's padding use it). */
:root{--bar-h:56px;--tabbar-h:0px;--scrim:color-mix(in srgb,var(--ink) 38%,transparent)}
:root[data-theme="dark"]{--scrim:rgba(0,0,0,.55)}
:is(.wbar,[id=tabs],.acmenu,.thdr,.shdlg,.ihint,.curx) [hidden]{display:none!important}
/* The shell's line icons (24 grid, 1.8 stroke). Scoped: .ic is also the video thumbs'. */
:is(.wbar,[id=tabs],.acmenu,.thdr,.shdlg,.ihint) .ic{display:block;flex:none;width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
:is(.wbar,[id=tabs],.acmenu,.thdr,.shdlg,.ihint) .ic *{vector-effect:non-scaling-stroke}
/* Full bleed over the body's gutters (the safe areas included), its row in the same column
   as the views (--maxw), sticky: the bar is the only thing that stays (F15). */
.wbar{position:sticky;top:0;z-index:30;background:var(--paper);border-bottom:2px solid var(--ink);
  margin-left:calc(-1 * max(16px,env(safe-area-inset-left,0px)));margin-right:calc(-1 * max(16px,env(safe-area-inset-right,0px)));
  padding:env(safe-area-inset-top,0px) max(16px,env(safe-area-inset-right,0px)) 0 max(16px,env(safe-area-inset-left,0px))}
.bar-in{max-width:var(--maxw);margin:0 auto;display:flex;align-items:center;gap:12px;min-height:var(--bar-h)}
.bhome{display:flex;align-items:center;min-height:44px;flex:none;color:var(--ink);text-decoration:none}
.wfl{display:block;height:26px;width:calc(26px * 650 / 116);color:var(--ink)}
.bhome .wfl-iso{display:none;font-size:30px;vertical-align:0}
.bpipe{width:1.5px;height:26px;background:var(--ink3);opacity:.55;flex:none}
/* The breadcrumb (js/header.js paintCrumbs): the context, then where you are (aria-current). */
.crumbs{min-width:0;flex:1}
.crumbs ol{list-style:none;margin:0;padding:0;display:flex;align-items:center;gap:6px;min-width:0;font-size:1rem}
.crumbs li{display:flex;align-items:center;gap:6px;min-width:0;white-space:nowrap}
.crumbs li:last-child{flex:0 1 auto}
.crumbs li+li::before{content:"›";color:var(--ink3);font-size:1.1rem}
.crumbs a{color:var(--ink2);text-decoration:none;font-weight:700;overflow:hidden;text-overflow:ellipsis;min-height:44px;display:inline-flex;align-items:center;min-width:0}
.crumbs a:hover{color:var(--ink);text-decoration:underline}
.crumbs a>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.crumbs li+li:last-child{flex-shrink:0}   /* E01-9: the context gives way to a long title, never "Hoy" */
/* E01-14: a context crumb that is no link (the trip on Hoy, Datos) ends in "…" as a link's does. */
.crumbs li>span:not([aria-current]){overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.crumbs [aria-current]{font-weight:700;color:var(--ink);overflow:hidden;text-overflow:ellipsis;min-width:0}
.bacts{display:flex;align-items:center;gap:8px;flex:none}
/* G5: one control family. A 44 px box, a 1.5 px --hair border (hover --ink), an icon, a short
   label only where the icon alone is ambiguous; pressed / open: filled with --ink. */
.ctl{display:inline-flex;align-items:center;justify-content:center;gap:6px;flex:none;min-width:44px;min-height:44px;padding:0 10px;
  border:1.5px solid var(--hair);color:var(--ink2);text-decoration:none;font-weight:700;font-size:.82rem;white-space:nowrap;background:var(--paper);-webkit-tap-highlight-color:transparent}
.ctl:hover{color:var(--ink);border-color:var(--ink)}
.ctl[aria-expanded="true"],.ctl[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.ctl.sq{padding:0;width:44px}
.cseg{display:inline-flex;flex:none}
.cseg .ctl+.ctl{border-left:0}
.cseg .ctl{min-width:44px;padding:0 9px}   /* E01-8: 44 px wide, the touch minimum */
.curx .cxn{display:none}
.acct-btn{font:700 .8rem var(--gothic);letter-spacing:.02em}
.acct-btn .acct-in:empty{display:none}
.acct-btn .acct-in:not(:empty)+.acct-sil{display:none}
/* Wide: the tabs row under the bar (sticky with it); the two groups on one line, each with
   its label in front; icon + name; the current one inked with the red underline. */
#tabs{max-width:var(--maxw);margin:0 auto;display:flex;align-items:stretch;border-top:1px solid var(--hair)}
#tabs .ngrp{display:flex;align-items:center;gap:4px}
#tabs .ngt{display:flex;align-items:stretch;gap:2px}
#tabs .ngrp+.ngrp{margin-left:18px;padding-left:18px;border-left:1px solid var(--hair)}
#tabs .ngl{font-size:.66rem;letter-spacing:.12em;text-transform:uppercase;color:var(--ink2);font-weight:700;margin-right:8px;white-space:nowrap}
#tabs .ngt button{display:flex;align-items:center;gap:7px;min-height:44px;padding:0 10px;font-weight:700;font-size:.92rem;color:var(--ink2);border-bottom:3px solid transparent;margin-bottom:-2px;white-space:nowrap}
#tabs .tic{width:18px;height:18px}
#tabs .ngt button:hover{color:var(--ink)}
#tabs .ngt button[aria-selected="true"]{color:var(--ink);border-bottom-color:var(--red)}
#tabs .ngt button[aria-selected="true"] .tic{color:var(--red)}
#tabs .tdesc,#tabs .tshx,#tabs .tshare,#tabs .tmore{display:none}
#tabs .tsh{display:contents}   /* wide: only its label, in front of the group */
/* 2026-11-01: nine tabs since Personas, and the row at full size needs ~1150 px (it already
   spilled past the window below ~1050 with eight). Narrower wide windows (a tablet, a small
   laptop) drop the group labels (still the tablists' names: aria-labelledby reads hidden
   text) and tighten the tabs; below 980 px each tab puts its icon over its name, as the
   phone's tab bar does. */
@media (min-width:720px) and (max-width:1199px) and (min-height:501px){
  #tabs .ngl{display:none}
  #tabs .ngrp+.ngrp{margin-left:8px;padding-left:8px}
  #tabs .ngt button{padding:0 7px;gap:5px;font-size:.86rem}
}
@media (min-width:720px) and (max-width:979px) and (min-height:501px){
  #tabs .ngt button{flex-direction:column;justify-content:center;gap:2px;padding:4px 6px 5px;font-size:.72rem}
  :root{--stick-h:calc(env(safe-area-inset-top,0px) + var(--bar-h) + 54px)}   /* the taller tabs row */
}
/* Wide: the bar and its tabs row stay on top (~bar + 46 px): what sticks below them (the costs'
   total) and what scrolls into view starts under them. The phone overrides both. */
:root{--stick-h:calc(env(safe-area-inset-top,0px) + var(--bar-h) + 48px)}
html{scroll-padding-top:var(--stick-h)}
/* Wide: Compartir lives in the bar; the trip header's copy is the phone's. */
.thdr .shr-btn{margin-left:auto;align-self:center}
@media (min-width:720px) and (min-height:501px){.thdr .shr-btn{display:none!important}}
/* G2: the account menu, under the account button. */
.acmenu{position:fixed;z-index:50;top:calc(env(safe-area-inset-top,0px) + var(--bar-h) + 6px);right:max(16px,calc((100vw - var(--maxw)) / 2));width:300px;max-height:calc(100dvh - var(--bar-h) - 24px);overflow:auto;
  background:var(--paper);border:1.5px solid var(--ink);box-shadow:0 10px 30px rgba(0,0,0,.18);padding:6px 0}
.acmenu[hidden]{display:none}
.acwho{padding:8px 14px 10px;border-bottom:1px solid var(--hair);margin-bottom:4px;display:flex;flex-direction:column;min-width:0;overflow-wrap:anywhere}
.acwho span{font-size:.8rem;color:var(--ink2)}
.acwho:has(b:empty){display:none}
.mitem{display:flex;align-items:center;gap:12px;min-height:48px;padding:6px 14px;text-decoration:none;color:var(--ink);width:100%;text-align:left;font-weight:400}
.mitem:hover{background:var(--land)}
.mitem[aria-current="page"]{box-shadow:inset 3px 0 0 var(--red);font-weight:700}
.mitem .ic{color:var(--ink2)}
.mitem[aria-current="page"] .ic{color:var(--red)}
.msep{height:1px;background:var(--hair);margin:6px 0}
.mrow{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:4px 14px;min-height:52px}
.acmenu .acph{display:none}
.scrim{position:fixed;inset:0;background:var(--scrim);z-index:29}
.scrim[hidden]{display:none}
/* The trip's header (scrolls with the page). */
.thdr{display:flex;align-items:flex-end;gap:14px;padding-top:16px;flex-wrap:wrap;max-width:var(--maxw);margin:0 auto}
.thdr .tmk{font-size:2.3rem;line-height:.9;color:var(--red)}
.thdr .t{display:flex;flex-direction:column;min-width:0;flex:1 1 220px}
.thdr .t>b{font-size:1.15rem;letter-spacing:.02em;overflow-wrap:anywhere}
.thdr .tline{display:flex;flex-wrap:wrap;align-items:center;gap:4px 12px}
.thdr #tsub{font-family:var(--mono);font-size:.75rem;color:var(--ink2)}
.thdr #tsub:empty{display:none}
/* 2026-11-01: who travels (#ttrv, js/views/viajeros.js), with two travellers or more: one link
   to Personas at the end of the dates line (on its own line when it does not fit). A ring per
   traveller with the initials, the principal's in red, at most five and then "+N"; the first
   names beside the rings on wide screens, initials only on the phone. 44 px tall (the rings
   are 28), the page's red focus ring. */
.thdr .ttrv{display:inline-flex;align-items:center;min-height:44px;margin-left:auto;padding:0 4px;max-width:100%;min-width:0;color:var(--ink);text-decoration:none;-webkit-tap-highlight-color:transparent}
/* Portrait phone: a line of its own under the dates and the clock (they rarely leave room),
   clear of the clock's 44 px tap box (its margins of -10 px reach into the next line). */
@media (max-width:719px) and (min-height:501px){
  .thdr .ttrv{flex-basis:100%;margin:6px 0 -6px;padding:0}
}
/* Phone: the mark, the title and the icon-only Compartir on the first row; the dates and the
   destination's clock under them, the whole width (the clock's
   text never cut, D143). */
@media (max-width:719px),(max-height:500px){
  .thdr{display:grid;grid-template-columns:auto minmax(0,1fr) auto;column-gap:14px;align-items:end}
  .thdr .t{display:contents}
  .thdr .tmk{grid-column:1;grid-row:1}
  .thdr .t>b{grid-column:2;grid-row:1;align-self:center}
  .thdr .tline{grid-column:1/-1;grid-row:2;min-width:0;margin-top:6px}
  .thdr .shr-btn{grid-column:3;grid-row:1;padding:0;width:44px;align-self:center}
  .thdr .shr-btn>span{display:none}
}
.facts{margin-top:10px}

/* ===== Phone (portrait, and landscape by height): the bottom tab bar ===== */
@media (max-width:719px),(max-height:500px){
  :root{--bar-h:52px}
  .wfl{height:21px;width:calc(21px * 650 / 116)}
  .bar-in{gap:9px}
  .bpipe{height:22px}
  .bacts{gap:6px}
  .bacts .bw{display:none!important}
  /* Signed out there is no account menu: the theme stays in the bar. */
  .wbar.anon .bacts .theme.bw{display:inline-flex!important}
  .acmenu{left:max(8px,env(safe-area-inset-left,0px));right:max(8px,env(safe-area-inset-right,0px));width:auto}
  .acmenu .acph{display:flex}
  .acmenu .msep.acph{display:block}
  /* The tab bar: En viaje's four and Planificar, icon over name. */
  #tabs{position:fixed;left:0;right:0;bottom:0;z-index:30;max-width:none;margin:0;background:var(--paper);border-top:2px solid var(--ink);
    padding:0 max(4px,env(safe-area-inset-right,0px)) env(safe-area-inset-bottom,0px) max(4px,env(safe-area-inset-left,0px));display:grid;grid-template-columns:repeat(5,minmax(0,1fr))}
  #tabs #tg-viaje,#tabs #tg-viaje .ngt{display:contents}
  #tabs .ngrp+.ngrp{margin:0;padding:0;border:0}
  #tg-viaje .ngl{display:none}
  #tabs .tmore{display:flex}
  #tg-viaje .ngt button,#tabs .tmore{flex-direction:column;justify-content:center;align-items:center;gap:2px;min-height:56px;padding:4px 0 6px;font-size:.7rem;font-weight:700;color:var(--ink2);
    border:0;border-top:3px solid transparent;margin:0;min-width:0}
  #tg-viaje .ngt button>span,#tabs .tmore>span{max-width:100%;overflow:hidden;text-overflow:ellipsis}
  /* E01-14: with a larger text the five labels shrink together until the longest fits
     (js/shell.js fitTabLabels sets --tab-fs); past that, icons alone, the names kept for
     VoiceOver (.tight). Never an ellipsis. */
  #tg-viaje .ngt button>span,#tabs .tmore>span{font-size:var(--tab-fs,inherit)}
  #tabs.stack :is(#tg-viaje .ngt button,.tmore){flex-direction:column;gap:2px;font-size:.7rem}
  #tabs.tight :is(#tg-viaje .ngt button>span,.tmore>span){position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
  #tabs .tic{width:22px;height:22px}
  #tg-viaje .ngt button[aria-selected="true"],#tabs .tmore.cur{border-top-color:var(--red);color:var(--ink)}
  #tabs .tmore.cur .tic{color:var(--red)}
  #tabs .tmore[aria-expanded="true"]{color:var(--ink)}
  /* Planificar: a sheet over the tab bar with its four sections (name + one line) and
     "Compartir el viaje". Closed unless #tabs.plan-open (js/shell.js). */
  #tabs #tg-plan{position:fixed;left:0;right:0;bottom:calc(58px + env(safe-area-inset-bottom,0px));display:none;flex-direction:column;align-items:stretch;
    background:var(--paper);border-top:2px solid var(--ink);padding:4px 0 8px;max-height:calc(100dvh - var(--bar-h) - 80px - env(safe-area-inset-top,0px));overflow:auto;overscroll-behavior:contain;
    box-shadow:0 -10px 30px rgba(0,0,0,.18);margin:0;border-left:0}
  #tabs.plan-open #tg-plan{display:flex}
  #tabs #tg-plan .ngt{display:flex}
  #tabs #tg-plan .tsh{display:flex;align-items:center;justify-content:space-between;padding:0 6px 0 14px}
  #tabs #tg-plan .tshx{display:inline-flex}
  #tg-plan .ngl{margin:0}
  #tg-plan .ngt{flex-direction:column;gap:0}
  #tg-plan .ngt button,#tabs .tshare{display:flex;align-items:center;gap:12px;min-height:56px;padding:6px 14px;border:0;margin:0;font-size:1rem;color:var(--ink);text-align:left;width:100%}
  #tg-plan .ngt button>span,#tabs .tshare>span{display:flex;flex-direction:column;line-height:1.3}
  #tg-plan .ngt button[aria-selected="true"]{box-shadow:inset 3px 0 0 var(--red)}
  #tg-plan .tic,#tabs .tshare .ic{color:var(--ink2)}
  #tg-plan .ngt button[aria-selected="true"] .tic{color:var(--red)}
  #tabs .tdesc,#tabs .tshare small{display:block;font-size:.78rem;color:var(--ink2);font-weight:400}
  #tabs .tshare{border-top:1px solid var(--hair);margin-top:6px;font-weight:700}
  #tabs .tshare[hidden]{display:none}
  /* Room for the tab bar under every trip view. */
  body[data-view]:not([data-view="home"]):not([data-view="account"]):not([data-view="wizard"]){--tabbar-h:calc(58px + env(safe-area-inset-bottom,0px));padding-bottom:calc(40px + var(--tabbar-h))}
  body.fit[data-view]{padding-bottom:var(--tabbar-h)!important}   /* D89's fitted map: no scroll, the sheet ends above the bar */
}
@media (max-width:520px){
  body[data-view="imap"]{padding-bottom:var(--tabbar-h)!important}   /* the fitted interactive map (imap.js fitBox) */
  /* The fitted maps want every pixel between the two bars: the trip's header steps aside
     there (the breadcrumb names the trip; its dates and clock are on Hoy). */
  body.fit .thdr,body.fit #tclock-p,body[data-view="imap"] .thdr,body[data-view="imap"] #tclock-p{display:none}
}
@media (max-width:719px),(max-height:500px){
  /* What scrolls into view (a focused field, a chip, a found place) stops above the tab bar and
     below the sticky bar, never under them (the root scroller cannot read body's --tabbar-h). */
  html:has(body[data-view]:not([data-view="home"]):not([data-view="account"]):not([data-view="wizard"])){scroll-padding-bottom:calc(66px + env(safe-area-inset-bottom,0px))}
  :root{--stick-h:calc(env(safe-area-inset-top,0px) + var(--bar-h) + 4px)}   /* the phone's tabs are at the bottom */
  /* iOS: with the keyboard up the fixed bar would ride over the field; it steps aside while
     the keyboard is there (html.kbd-up, js/shell.js: a focused text field and a visual viewport
     shrunk by it; a hardware keyboard or a field merely focused keep the bar). */
  html.kbd-up #tabs{display:none}
  html.kbd-up body[data-view]{--tabbar-h:0px!important}
}
/* Portrait phone: a two-line breadcrumb, the context small above, where you are below. */
@media (max-width:719px) and (min-height:501px){
  .crumbs ol{flex-direction:column;align-items:flex-start;gap:0;line-height:1.15}
  .crumbs li{max-width:100%}
  .crumbs li+li::before{content:none}
  /* E01-14: the level above and where you are (a subsection: its section over it). */
  .crumbs li:not(:nth-last-child(-n+2)){display:none}
  /* The small context line is no link of its own (it could not be 44 px tall)... */
  .crumbs li:not(:last-child) a{min-height:0;pointer-events:none}
  /* E18-24: the title scale's 11.5 px caps (.tsec h3), not 10.5. */
  .crumbs li:not(:last-child) :is(a,span){font-size:.72rem;letter-spacing:.04em;text-transform:uppercase;color:var(--ink2);font-weight:700}
  /* E01-15: with the system's text at 200 % the two lines (23 + 32 px) outgrew the bar and
     touched its top edge; they grow up to what the bar holds (14 + 22 px, ~42 px tall), then
     the "…" of a long name (the screen's h1, under the bar, keeps the large text). */
  .crumbs ol{font-size:min(1rem,22px)}
  .crumbs li:not(:last-child) :is(a,span){font-size:min(.72rem,14px)}
  /* ...the way up is (js/header.js paintCrumbs, li.up): "‹ CUENTA" over a section of Cuenta,
     "‹ <TRIP>" over a section of the trip, "‹ COSTOS" over one of its sub-tabs. Its tap area is
     the whole breadcrumb (two lines, the bar's 52 px tall), as iOS's back button. E18-24: the
     link's own box is the one thing hit there (the current page's line is under it). */
  .crumbs{position:relative;align-self:stretch;display:flex;align-items:center}
  .crumbs li.up a{pointer-events:auto;position:static}
  /* The link's own box is 44 px tall too, its line still 1.15em in the stack: negative block
     margins give back what the box adds (any text size, E01-15's 200 % included). */
  .crumbs li.up a{min-height:44px;margin-block:calc(.575em - 22px)}
  .crumbs li.up a::before{content:"‹";font-size:1.6em;line-height:0;letter-spacing:0;margin-right:5px}
  .crumbs li.up a::after{content:"";position:absolute;inset:0;z-index:1}
}
/* Phone landscape (F15): a 46 px bar, the tab bar's icon beside its name. */
@media (max-height:500px){
  :root{--bar-h:46px}
  html:has(body[data-view]:not([data-view="home"]):not([data-view="account"]):not([data-view="wizard"])){scroll-padding-bottom:calc(54px + env(safe-area-inset-bottom,0px))}
  .thdr{padding-top:8px}
  .thdr .tmk{font-size:1.7rem}
  #tg-viaje .ngt button,#tabs .tmore{flex-direction:row;gap:8px;min-height:44px;padding:0;font-size:.82rem}
  #tabs .tic{width:20px;height:20px}
  #tabs #tg-plan{bottom:calc(46px + env(safe-area-inset-bottom,0px));left:auto;width:min(420px,60vw);right:max(4px,env(safe-area-inset-right,0px));border:1.5px solid var(--ink);border-bottom:0}
  #tg-plan .ngt button,#tabs .tshare{min-height:48px}
  body[data-view]:not([data-view="home"]):not([data-view="account"]):not([data-view="wizard"]){--tabbar-h:calc(46px + env(safe-area-inset-bottom,0px))}
  /* E01-9: the account menu (~450 px in one column) does not fit the landscape phone's height:
     two columns, the places (who, Mis viajes, Cuenta, Admin) left and the settings and actions
     (Tema, Moneda, Recomendar, Salir) right; under the bar's right end, clear of the notch. */
  .acmenu{left:auto;width:min(560px,calc(100vw - max(8px,env(safe-area-inset-left,0px)) - max(8px,env(safe-area-inset-right,0px))));
    max-height:calc(100dvh - var(--bar-h) - 12px - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px));columns:2;column-gap:0;column-rule:1px solid var(--hair)}
  .acmenu>*{break-inside:avoid}
  .acmenu .msep.acph{display:none}
  .acmenu .msep.acph+.mrow{break-before:column}
}
/* E01-14: "Wayfolio." stays on screen on the narrowest phones (it was the 旅 alone at <= 379 px):
   the lockup a little smaller, so the breadcrumb and the two controls still fit at 320. */
@media (max-width:379px){.wfl{height:16px;width:calc(16px * 650 / 116)}.bar-in{gap:7px}.bacts{gap:5px}}
/* Narrower than any phone (a 200 % zoom leaves ~200 px): the 旅 alone, or the controls do not fit. */
@media (max-width:299px){.bhome .wfl{display:none}.bhome .wfl-iso{display:inline-block}}
/* ===== E03: the floating Feedback button (#fb-fab, js/feedback-app.js) =====
   Bottom-right on every size: above the phone's tab bar (--tabbar-h, safe area included) or
   the home indicator, clear of the notch's side in landscape; the window's corner on a
   desktop (the page's margin at 1280 and up). Left is taken on the phone's maps (the scale
   and the OSM credit sit bottom-left) and the update/outdated notices are centred, so the
   right corner is the one that meets nothing; with a notice up (body.sw-bar) it rises
   above it. z-index 28: under the scrim (29), the tab bar and its sheets (30-31), the menu,
   the sheets and dialogs, so an overlay covers it even where :has() is missing (iOS < 15.4);
   with :has() it is hidden outright. Hidden by visibility (not display): it keeps its box,
   so js/feedback-app.js can tell when a map's Capas button scrolls under it (body.fab-yield:
   it steps aside until the button has passed). No transition: the house style does not animate. */
/* E29-6 (the human, 2026-11-02): a round chat bubble read as a support chat, its "Dar
   feedback" only a hover title (never on the phone). Now a pill with the bubble and the word
   "Feedback", which is its accessible name too (no aria-label to drift from it). It is the
   app's primary button (.dbtn.pri: ink on paper, bold .88rem, the same 20 px icon and 8 px gap
   as Recomendar's .hrec-b), in a pill and with a paper ring and a shadow because it floats on
   the content and the maps. 48 px tall (52 at most with 200 % text, line-height 1.2), so the
   room kept under the page (76 px, below) still holds; its width (it grows with the text) is
   published by js/feedback-app.js as --fab-w for the foot's strip on a wide screen. */
.fbfab{position:fixed;z-index:28;right:max(16px,calc(env(safe-area-inset-right,0px) + 8px));
  bottom:calc(max(var(--tabbar-h,0px),env(safe-area-inset-bottom,0px)) + 14px + var(--fab-lift,0px));
  display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:48px;min-width:48px;
  max-width:calc(100vw - 32px);padding:6px 18px 6px 14px;margin:0;border-radius:999px;
  background:var(--ink);color:var(--paper);border:1.5px solid var(--paper);box-shadow:0 3px 12px rgba(0,0,0,.28);
  font-weight:700;font-size:.88rem;line-height:1.2;white-space:nowrap;cursor:pointer;-webkit-tap-highlight-color:transparent}
.fbfab .ic{display:block;flex:none;width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.fbfab-t{display:block}
.fbfab:not(:disabled):hover{background:color-mix(in srgb,var(--ink) 86%,var(--red));color:var(--paper)}
.fbfab:focus-visible{outline:3px solid var(--red);outline-offset:3px}
.fbfab[hidden]{display:none}
body.sw-bar{--fab-lift:calc(var(--swbar-h,44px) + 14px)}
/* Hidden while something is on top: a dialog (native or soft), a sheet (.pe, search, taxi,
   documents, the map's Capas), the account menu, Planificar; and while typing (below). */
body:has(dialog[open],.sdlg-bd,.pe:not([hidden]),.srch:not([hidden]),.taxi:not([hidden]),.dsheet:not([hidden]),#acmenu:not([hidden]),#tabs.plan-open,.lsheet.open,.scrim:not([hidden])) .fbfab,
html.kbd-up .fbfab,body.fab-yield .fbfab{visibility:hidden}
@media (max-width:719px),(max-height:500px){
  /* The typing guard, on the phone: a focused text field means the keyboard (or soon). */
  body:has(:is(input:not([type=checkbox],[type=radio],[type=button],[type=submit],[type=reset],[type=range],[type=color],[type=file]),textarea,select,[contenteditable="true"]):focus) .fbfab{visibility:hidden}
}
/* ===== E01-13 (the human, 2026-11-01): the app's foot on a wide screen =====
   A short Viajes page left the foot halfway down the window, a white gap under it and the
   floating Feedback button alone in the corner. Wide (the shell's breakpoint: not the phone,
   whose foot simply ends the page's content, above the tab bar and the button's room), on
   every screen with the foot (the Home and body.foot-x: a trip's views, the account screens;
   js/home.js paintFootHost): body is a column at least the window's height, the view on
   screen grows, and the foot ends on the window's bottom edge; a long page ends with it as
   before. The trip's header rows (.thdr, the clocks, .facts, the empty notice, Mapa's
   sub-tabs) are centred by auto margins, which in a column would shrink them to their
   content: they keep the full width (their max-width still holds). On those screens body's
   bottom room (40 px, the button's 76, the update notice's) moves into the foot, so its
   border and its rows sit on the edge, the notice's room still under them. The button keeps
   its corner: the foot keeps the strip it covers free (padding-right), only where the window
   is too narrow for the column's margin to hold it (0 once the column ends left of it). */
@media (min-width:720px) and (min-height:501px){
  body:is([data-view="home"],.foot-x){display:flex;flex-direction:column;min-height:100vh;min-height:100dvh}
  /* E01-14: the views and the trip's header rows are in <main>, which takes the column's width
     and grows; inside it they flow (and centre) as on the phone. */
  body:is([data-view="home"],.foot-x)>main{width:100%;flex:1 0 auto}
  html body:is([data-view="home"],.foot-x){padding-bottom:0}
  body:is([data-view="home"],.foot-x)>.hpfoot{padding-bottom:calc(16px + env(safe-area-inset-bottom,0px))}
  body.sw-bar:is([data-view="home"],.foot-x)>.hpfoot{padding-bottom:calc(var(--swbar-h,44px) + 22px + env(safe-area-inset-bottom,0px))}
}
.role{display:flex;gap:10px;align-items:flex-start;border:1.5px solid var(--hair);padding:10px 12px;min-height:56px;cursor:pointer}
.role:has(input:checked){border-color:var(--ink);box-shadow:inset 0 -3px 0 var(--red)}
.role input{accent-color:var(--red);margin-top:4px;width:18px;height:18px;flex:none}
.role b{display:block}
.role .small{display:block}
/* ===== E18-18 (the human: "tengamos consistencia en toda la UI"): one component per role, the
   same everywhere. This block restates, at the end of the sheet (so it wins over the older
   per-screen rules with the same selectors), the one variant of links, destructive buttons,
   chips and button sizes. Button labels start upper-case (C1): that is in the markup. */
/* C2 links. An internal action ("ver todos ›", "seguí cargándolo", "Cuenta ›", "¿Olvidaste tu
   contraseña?") is red, bold, never underlined (underlined on hover), at ONE size, .8rem, when
   it stands alone or closes a line. A link inside a sentence (a place, "Personas", "Viajes")
   is the same red bold at the sentence's size. Underlined ink is only for the foot (#h-foot)
   and external pages (Esenciales' sources, the legal pages inside a sentence). No link is ever
   the browser's blue: a link no rule names takes the text's colour. */
a{color:inherit}
.maplink,.bmap-l .maplink,.dleg .maplink,.dacts .maplink,.rsvi .dlinks .maplink,.alinks .maplink,.nfoot .maplink,
.tcl a,.hacc a,.hresume a,.csum .ctr a,.csum .cimain .cbudno a,.tev .evl,.tgo .plink.in,.book .go,button.go,
.hdue h3 a,.hmiss a,.hcard a.hload,.hhero a.hload,.htaxi,p.lcline button.plink,.shdlg .shppl a,#empty-go .quiet a{
  color:var(--red);font-weight:700;font-size:.8rem;text-decoration:none;letter-spacing:0}
.vfollow a,.pptw a,.hlater a,a.hcl{color:var(--red);font-weight:700;text-decoration:none}
:is(.maplink,.tcl a,.go,.hdue h3 a,.hmiss a,.htaxi,p.lcline button.plink,.shdlg .shppl a,#empty-go .quiet a,.vfollow a,.pptw a,.hlater a,a.hcl):hover{color:var(--red);text-decoration:underline;text-underline-offset:3px}
.elnk,.efoot .elnk,.eembf .elnk,.small[data-legal] a{color:var(--ink);text-decoration:underline;text-decoration-color:var(--ink3);text-underline-offset:3px}
/* C6: one destructive style, .dbtn.danger (the admin panel's .btn.danger, admin/index.html):
   red border and text; as the question's answer (ask(): {danger: true}) or a screen's primary,
   .dbtn.pri.danger, filled with --redbg (white on it >= 4.5:1 in both themes). Every action
   that deletes, takes someone out or closes a session wears it: Borrar, Sacar, Revocar, Salir,
   Quitar la contraseña, Desvincular, Cerrar (sesiones), Abandonarlo, Dejar de compartir. Taking
   a row out of a form before saving it is not destructive: "Quitar", .dbtn.sec (D-d). Red is
   never the only cue: the verb says it. */
.dbtn.danger,.dsheet .dbtn.danger{border-color:var(--red);color:var(--red);font-weight:700}
.dbtn.danger:not(:disabled):hover,.dbtn.pri.danger,.dsheet .dbtn.pri.danger{background:var(--redbg);border-color:var(--redbg);color:#fff}
/* C14: one chip, .pill. The trip's status chip is the same on Mis viajes (hero and cards: over a
   cover it needs its white ground), Hoy and Estado del viaje; Cuenta's "este dispositivo"
   (.atag) is a .pill too. */
:is(.pill.hst,.pill[class*="lc-"]):not(.st-ongoing):not(.lc-en_curso){background:var(--white)}
/* The other small mono chips (a stop's "vibe" tags, a booking's priority, a due item's kind)
   are the pill's shape and type; each keeps its own colour. */
.vtag,.prio,.hdk{font:500 .68rem var(--mono);border-width:1.5px;border-radius:3px;padding:0 5px}
/* C16: one button system, three sizes. .dbtn (.88rem, 6 x 16 px) everywhere; the small row
   action (.8rem, 4 x 12 px: "Ya lo hice", "Ver en el mapa", "Copiar", "Editar" of a stop);
   the large call to action of a screen (1rem, 50 px: Mis viajes' hero, the wizard). Height:
   44 px (50 the large one). */
.cfx .dbtn,.ephr .ecopy,.hstart.compact .hsteps .dbtn,.peed{font-size:.8rem;padding:4px 12px}
.taxibtn,.peadd,.hact .dbtn,.pfbtn{font-size:.88rem;padding:6px 16px}
.wzbig{min-height:50px}
/* Entrar, Recuperar, Crear tu cuenta…: every button of the card as wide as "Entrar con Google"
   (.gbtn), not one full width and the next as wide as its text. */
.acard:not(.wide) .aform .dbar .dbtn,.acard:not(.wide)>.dbar .dbtn{width:100%;max-width:360px}
/* ===== E18-18 (C19): the styles js/ui-e2.js, js/recommend.js and js/feedback.js used to
   inject at run time (one <style> each). Here, at the end, they keep the cascade they had;
   their dialogs and buttons are the app's (.dbtn, .dlgx, --scrim: see .dlgx above). ===== */
/* ===== IAM E2-E: trip lifecycle (js/lifecycle.js) ===== */
.pill.lc-confirmado{border-color:var(--dtct);color:var(--dtct)}
.pill.lc-en_curso{border-color:var(--redbg);background:var(--redbg);color:#fff}
.pill.lc-finalizado{border-color:var(--ink3);color:var(--ink2)}
.pill.lc-abandonado{border-color:var(--ink3);color:var(--ink2);border-style:dashed}
.pill.lc-planificacion{border-color:var(--ink);color:var(--ink)}
.pill[data-stage="abandonado"]{border-style:dashed;border-color:var(--ink3);color:var(--ink2)}

/* ===== IAM E2-E: personal medical card, sharing, insurance ===== */
.emask{border-left:3px solid var(--red);padding:6px 10px;margin:8px 0;display:flex;flex-direction:column;gap:6px;font-size:.88rem}
.emask .dbar .dbtn{min-height:44px}
.fbdlg .dbtn,.recdlg .dbtn{min-height:44px;display:inline-flex;align-items:center;justify-content:center}
/* ===== E01-14, E18-26 (mobile-qa, 2026-11-01): structure and the last strays of D203 =====
   At the end of the sheet, so it wins over the older per-screen rules with the same selectors. */
/* The screen's h1 (#scr-h1, js/header.js) steps aside on the empty Home: its big title is the h1 there. */
body[data-view="home"]:has(#h-empty:not([hidden])) #scr-h1{display:none}
/* A fold says it opens (Personas' "Invitar a alguien", Datos' and the wizard's): the red ▸ / ▾
   after its words, as Hoy's folds (.tedit); on a touch screen the browser's own triangle is
   gone (the summary is a 44 px flex row). */
.dfold>summary{list-style:none}
.dfold>summary::-webkit-details-marker{display:none}
.dfold>summary::after{content:"▸";color:var(--red);margin-left:.35em}
.dfold[open]>summary::after{content:"▾"}
.hcov,.bmapa{text-decoration:none}
.bmap-go,.bmap-hint{font-size:.8rem;color:var(--red)}
/* C10: one title scale. Every inner title (h4: Costos' and Cuentas' groups, the reservations',
   a traveller's, a place's day, Datos' counts, Presupuesto's "Supuestos") is .tsec h3's
   .72rem caps; Ritmo's group titles (.rgh) are bold like every other title (the parts in
   the text face keep theirs). */
.tsec h4,.resv-wrap h4,.csec h4,.cacc h4,.eself h4,.pdh,.totsh{font-size:.72rem}
/* C5: one empty state, .empty at .88rem wherever it sits (a view's rule such as .tsec p no
   longer changes it); #empty, a whole view's, keeps its centred box at the same size. */
.empty.empty{font-size:.88rem}
#empty{font-size:.88rem}
/* E04-5: "¿Cómo…?", the one link from a screen to its guide (js/views/ayuda.js howtoHtml; the
   static ones carry the same markup): the internal link (.maplink) with the help icon, on its
   own 44 px line under what it explains. */
.howto{margin:4px 0 8px}
.howto .maplink{display:inline-flex;align-items:center;gap:6px;min-height:44px;white-space:normal}
.howto .ic{flex:none;width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
