﻿/* Ported from backend/Dokola.Api/wwwroot/me.html so the native app and the web athlete
   page look like one product. Keep the two in sync when either changes. */

:root {
  --bg:#0b1020; --panel:#141b30; --panel2:#1b2440; --line:#263255; --text:#e8ecf6;
  --muted:#8a96b8; --accent:#4cc9f0; --live:#06d6a0; --male:#5580b4; --female:#cf7f7f;
}

* { box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
html, body { margin:0; background:var(--bg); color:var(--text);
  font-family:"Segoe UI", system-ui, -apple-system, sans-serif; -webkit-font-smoothing:antialiased;
  overscroll-behavior:none; }
/* The native app sets viewport-fit=cover, so the page really does extend under the
   status bar and the notch — without these the first heading is drawn behind the clock.
   The bottom inset was already handled on .tabbar; the top and sides were not. In a
   browser these resolve to zero, so the web app is unaffected. */
body { max-width:540px; margin:0 auto;
  padding-top:env(safe-area-inset-top);
  padding-left:env(safe-area-inset-left);
  padding-right:env(safe-area-inset-right); }

.pad { padding:16px 14px; }
h1 { font-size:22px; margin:0; display:flex; align-items:center; gap:8px; }
h2 { font-size:15px; margin:0 0 8px; color:var(--muted); font-weight:600; }
.muted { color:var(--muted); }

.live-dot { width:10px; height:10px; border-radius:50%; background:var(--muted); display:inline-block; }
.live-dot.on { background:var(--live); box-shadow:0 0 0 0 rgba(6,214,160,.7); animation:pulse 1.6s infinite; }
@keyframes pulse {
  0% { box-shadow:0 0 0 0 rgba(6,214,160,.6) }
  70% { box-shadow:0 0 0 9px rgba(6,214,160,0) }
  100% { box-shadow:0 0 0 0 rgba(6,214,160,0) }
}

.card { background:var(--panel); border:1px solid var(--line); border-radius:14px; padding:14px; margin-top:12px; }
label { display:block; font-size:13px; color:var(--muted); margin:10px 0 5px; }
input, textarea, select { width:100%; padding:13px; font-size:17px; border-radius:10px;
  border:1px solid var(--line); background:var(--panel2); color:var(--text);
  font-family:inherit; }
/* Typing a paragraph into a one-line box is how people give up on writing to you. */
textarea { resize:vertical; min-height:88px; line-height:1.4; }
button { font:inherit; cursor:pointer; border:none; border-radius:10px; }
.btn { width:100%; padding:14px; font-size:16px; font-weight:700; background:var(--accent); color:#04121a; margin-top:14px; }
.btn.ghost { background:var(--panel2); color:var(--text); border:1px solid var(--line); }
.btn.stop { background:#ff6b6b; color:#2a0808; }
.err { color:#ff6b6b; font-size:14px; margin-top:10px; min-height:18px; }
.note { font-size:12px; color:var(--muted); margin-top:10px; line-height:1.5; }

/* A download measured in hundreds of megabytes needs something that visibly moves, or a
   rider on a slow connection concludes it has hung and kills the app. */
.bar { height:10px; border-radius:6px; background:var(--line); overflow:hidden; margin:10px 0; }
.bar .fill { height:100%; background:var(--live); transition:width .25s linear; }
.chip { display:inline-flex; align-items:center; justify-content:center; min-width:28px; height:28px; padding:0 7px;
  border-radius:8px; color:#fff; font-weight:800; font-size:14px; }

/* Home race list */
.race { display:flex; align-items:center; justify-content:space-between; padding:16px 14px; cursor:pointer; }
.race + .race { border-top:1px solid var(--line); }
.race .n { font-weight:700; font-size:17px; }
.race .d { font-size:13px; color:var(--muted); margin-top:3px; }
.race .go { color:var(--accent); font-size:22px; }

/* Race header + tabs */
.rhead { display:flex; align-items:center; justify-content:space-between; padding:14px; border-bottom:1px solid var(--line); }
.rhead .rn { font-weight:700; font-size:17px; display:flex; align-items:center; gap:8px; }
.rhead .rs { font-size:12px; color:var(--muted); margin-top:2px; }

/* Links, at last.
   Nothing in this stylesheet had ever said what a link looks like, so every one of them
   came out in the browser's own blue with an underline, and turned purple once visited —
   which on a dark phone screen looks like a mistake, because it is one. */
a { color:var(--accent); text-decoration:none; }
a:visited { color:var(--accent); }
/* A link dressed as a button keeps the button's own colours once it has been visited.
   Pavel, 10. 10.: after going back to the front page the label on "Virtuální závody"
   was gone — a:visited had painted the text the colour of the button behind it. */
a.btn, a.btn:visited { color:#04121a; }
a.btn.ghost, a.btn.ghost:visited { color:var(--text); }
.htile, .htile:visited, .rcard, .rcard:visited, .mcard, .mcard:visited,
.mrow, .mrow:visited, .hstats, .hstats:visited, .hrow, .hrow:visited { color:var(--text); }
a:active { opacity:.7; }
.rs a { color:var(--accent); }

/* The account menu. Full-width rows, because a thumb on handlebars is not a mouse. */
.menu-button { width:40px !important; margin:0 !important; padding:8px 0 !important;
               font-size:20px; line-height:1; }

.menu { display:flex; flex-direction:column; background:var(--panel);
        border:1px solid var(--line); border-radius:14px; overflow:hidden;
        margin-bottom:14px; }
.menu a { padding:14px; color:var(--text); font-size:15px; }
.menu a + a { border-top:1px solid var(--line); }
.menu a.danger { color:#ff6b6b; }
.panel { display:none; }
.panel.active { display:block; }
.tabbar { position:sticky; bottom:0; display:flex; background:var(--panel); border-top:1px solid var(--line);
  padding-bottom:env(safe-area-inset-bottom); }
.tabbar button { flex:1; background:transparent; color:var(--muted); padding:12px 4px 14px; font-size:12px; font-weight:600; }
.tabbar button .ic { display:block; font-size:20px; margin-bottom:2px; }
.tabbar button.active { color:var(--accent); }

/* My status */
/* As many columns as there are numbers. It was fixed at three, and the organiser's
   board has four — which put "Dojelo" on a line of its own underneath. */
.status { display:grid; grid-template-columns:repeat(auto-fit,minmax(64px,1fr));
          text-align:center; }
.status .k { font-size:12px; color:var(--muted); }
.status .v { font-size:22px; font-weight:800; font-variant-numeric:tabular-nums; margin-top:2px; }

/* Opponent rows */
.op { display:flex; align-items:center; gap:11px; padding:12px 4px; border-bottom:1px solid rgba(38,50,85,.55); }
.op:last-child { border-bottom:none; }
.op .who { flex:1; min-width:0; }
.op .nm { font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.op .sub { font-size:12px; color:var(--muted); margin-top:3px; }
.op .min { text-align:right; }
.op .min .t { font-size:22px; font-weight:800; font-variant-numeric:tabular-nums; line-height:1.05; }
.op .min .rel { font-size:11px; color:var(--muted); }
.up { color:var(--female); font-weight:700; }
.down { color:var(--live); font-weight:700; }

/* Source-of-position segmented control */
.seg { display:flex; background:var(--panel2); border:1px solid var(--line); border-radius:10px; overflow:hidden; margin-top:6px; }
.seg button { flex:1; padding:10px; background:transparent; color:var(--muted); font-weight:600; border-radius:0; }
.seg button.active { background:var(--accent); color:#04121a; }
/* The sport tiles (14. 10.): three to a row on a phone, the chosen one in the accent. */
.sports { display:grid; grid-template-columns:repeat(3, 1fr); gap:8px; margin-top:6px; }
.sports button { display:flex; flex-direction:column; align-items:center; gap:4px; padding:10px 4px; background:var(--panel2); border:1px solid var(--line); border-radius:10px; color:var(--muted); font-weight:600; font-size:13px; }
.sports button.on { background:var(--accent); border-color:var(--accent); color:#04121a; }
.sports button:disabled { opacity:.6; }
.sporttag { display:inline-flex; align-items:center; gap:4px; font-size:12px; color:var(--muted); }

#map { width:100%; height:70vh; background:#0f1730; }
.maphint { font-size:12px; color:var(--muted); padding:8px 14px; }
.leaflet-container { background:#0f1730; }

/* Blazor's unhandled-error strip, restyled to match. */
#blazor-error-ui {
  background:#ff6b6b; color:#2a0808; bottom:0; display:none; left:0; padding:12px 14px;
  position:fixed; width:100%; z-index:1000;
}
#blazor-error-ui .dismiss { cursor:pointer; position:absolute; right:12px; top:10px; }

/* ---------- Route library, recording, and riding the ghost ---------- */

/* The verdict, sized to be readable at 25 km/h with the phone on the bars. Colour does
   the reading; the words underneath confirm it. */
.ghostbar { padding:14px; text-align:center; border-bottom:1px solid var(--line); background:var(--panel); }
.ghostbar .delta { font-size:28px; font-weight:800; font-variant-numeric:tabular-nums; }
.ghostbar .against { font-size:12px; color:var(--muted); margin-top:4px; }
.ghostbar.ahead { background:rgba(6,214,160,.14); }
.ghostbar.ahead .delta { color:var(--live); }
.ghostbar.behind { background:rgba(255,107,107,.14); }
.ghostbar.behind .delta { color:#ff6b6b; }
.coachbar { padding:8px 14px; text-align:center; font-size:13px; font-weight:600; border-bottom:1px solid var(--line); background:var(--panel); font-variant-numeric:tabular-nums; }

.offroute { background:#ff6b6b; color:#2a0808; font-weight:700; text-align:center; padding:10px 14px; }

/* The turn ahead. Big enough to read at a glance from the bars, and it goes green and
   grows when the corner is on top of the rider — at that point they are not reading a
   number, they are checking they heard right. */
.turn { display:flex; align-items:center; justify-content:center; gap:14px;
        padding:10px 14px; background:var(--panel); border-bottom:1px solid var(--line); }
.turn .arrow { font-size:38px; line-height:1; font-weight:700; }
.turn .what { text-align:left; }
.turn .tdist { font-size:26px; font-weight:800; font-variant-numeric:tabular-nums; line-height:1.1; }
.turn .tdir { font-size:13px; color:var(--muted); }
.turn.now { background:rgba(6,214,160,.18); }
.turn.now .arrow, .turn.now .tdist { color:var(--live); }
.turn.now .tdir { color:var(--text); }

/* ---- The map's own furniture ------------------------------------------------
   MapLibre draws no markers of its own and has no layer switcher, so the dots, the
   source buttons and the rotation toggle are ours. Sized for a thumb on handlebars
   rather than a mouse. */

.mapdot { border-radius:50%; box-sizing:border-box; }
.mapdot.me     { width:18px; height:18px; background:#4cc9f0; border:3px solid #fff;
                 box-shadow:0 0 0 1px rgba(0,0,0,.35); }
.mapdot.ghost  { width:15px; height:15px; background:#8a96b8; border:2px solid #fff; opacity:.8; }
.mapdot.start  { width:13px; height:13px; background:#06d6a0; border:2px solid #fff; }
.mapdot.finish { width:13px; height:13px; background:#ff6b6b; border:2px solid #fff; }

/* Stacked, not in a row. MapLibre sizes every control button as a 29px square, which
   squeezes "OpenStreetMap" into nothing, and a row of three names is wider than a phone
   even once that is overridden. The !important is aimed at MapLibre's own rules, not at
   ours. */
/* The board's own furniture. A row that needs looking at is tinted rather than shouted
   at — an organiser scanning a hundred and fifty names needs to find the four, not be
   alarmed by them. */
.race.worry { background:rgba(255,209,102,.12); }
.race .bib { min-width:34px; text-align:center; font-weight:800; font-size:15px;
             color:var(--muted); }
.status .v.warn { color:#ffd166; }

.legend { display:flex; flex-wrap:wrap; gap:14px; margin-top:10px;
          font-size:12px; color:var(--muted); }
.legend span { display:flex; align-items:center; gap:6px; }
.legend i { width:14px; height:14px; border-radius:7px; }

/* A whole field on one map. The number is the bib, because that is what an organiser
   shouts down the phone. Colour carries the state and the legend says what it means —
   nobody should have to learn it. */
.mapdot.rider { width:26px; height:26px; border-radius:13px; border:2px solid #fff;
                display:flex; align-items:center; justify-content:center;
                font-size:11px; font-weight:700; color:#04121a; background:#4cc9f0;
                box-shadow:0 1px 4px rgba(0,0,0,.45); }
.mapdot.rider.Stopped  { background:#ffd166; }
.mapdot.rider.Silent   { background:#8a96b8; color:#0b1020; border-color:#ff6b6b; }
.mapdot.rider.Paused   { background:#b8c0d9; }
.mapdot.rider.Finished { background:#06d6a0; }
/* Off the course, and has said why. Amber like every other "read this, it is not an
   error" on these screens — the same colour the organiser's own messages wear. */
.mapdot.rider.Detour { background:#ffd166; }

/* Live tracking (Pavel, 15. 10.): the others in my group, and the one person I am
   watching. Orange, so a friend is never mistaken for my own blue dot; grey once the
   last fix is more than a few minutes old. */
.mapdot.rider.Friend { background:#f4a261; }
.mapdot.rider.Friend.Old { background:#8a96b8; color:#0b1020; }
.mapdot.rider.Self   { background:#4cc9f0; }

/* The lists on Živé sledování and the group map: a name with its live dot, and what to do. */
.live-row  { display:flex; align-items:center; gap:10px; padding:10px 0; border-top:1px solid var(--line); }
.live-row:first-of-type { border-top:0; }
.live-name { font-weight:600; display:flex; align-items:center; gap:8px; }
.live-code { font-size:28px; font-weight:800; letter-spacing:.2em; text-align:center; margin:12px 0 6px;
             font-variant-numeric:tabular-nums; }

.map-sources { display:flex; flex-direction:column; width:auto !important; }
.map-sources button { width:auto !important; height:auto !important;
                      margin:0; padding:7px 10px; font-size:12px; font-weight:600;
                      border:0; border-radius:0; background:#fff; color:#2b3250;
                      cursor:pointer; text-align:left; white-space:nowrap; }
.map-sources button + button { border-top:1px solid rgba(0,0,0,.12); }
.map-sources button.on { background:var(--live); color:#04121a; }
.map-sources button.off { opacity:.45; text-decoration:line-through; }
.map-notice { max-width:240px; padding:8px 10px; border-radius:8px; font-size:13px; line-height:1.35;
              background:rgba(15,23,48,.92); color:#fff; box-shadow:0 2px 8px rgba(0,0,0,.3); cursor:pointer; }

/* North up, or turning with the rider. The arrow points up when the map is locked to
   north and is coloured when it is following the rider's direction, so which mode you
   are in is readable at a glance from the bars. */
.map-rotate { font-size:17px; line-height:1; cursor:pointer; width:29px !important; }
.map-rotate span { display:inline-block; transform:rotate(-90deg); }
.map-rotate.on { background:var(--live); color:#04121a; }

/* Mandatory, not decorative: developer.mapy.com requires the logo above the map at 30 px
   or more, no smaller than any other logo on it, linking to mapy.com and alongside the
   credit text. A plain light background rather than MapLibre's control chrome, which
   would dim it. */
.map-provider-logo { background:rgba(255,255,255,.85); border-radius:6px;
                     padding:3px 6px; line-height:0; box-shadow:none !important;
                     margin:0 0 4px 4px !important; }
.map-provider-logo img { display:block; }

/* The map is a fixed slab rather than #map's 70vh: these screens have controls above and
   below it that must both stay reachable without scrolling on a phone. */
.routemap-wrap { margin-top:12px; border:1px solid var(--line); border-radius:14px; overflow:hidden; }
.routemap { width:100%; height:44vh; min-height:220px; background:#0f1730; }

.checkline { display:flex; align-items:center; gap:10px; margin-top:14px; color:var(--text); font-size:14px; }
.checkline input { width:auto; }

/* Sign-in choices on the web front page. */
.signin { display:flex; flex-direction:column; gap:10px; margin-top:10px; }
.signin .or { text-align:center; font-size:12px; color:var(--muted); margin:4px 0; }

/* An unfinished recording, offered rather than resumed behind the rider's back. */
.card.resume { border-color:var(--accent); }
.note.safe { color:var(--live); }
/* An imported file that will draw straight lines: worth reading, not an error. */
.note.warn { color:#ffd166; }

/* What the organiser has said mid-race. Amber rather than red: it is important and it is
   not an error, and the off-route banner already owns red on this screen. */
.notices { padding:0 14px; }
.notice {
    border-left:3px solid #ffd166; background:rgba(255,209,102,.08);
    border-radius:0 8px 8px 0; padding:8px 12px; margin-bottom:8px;
}
.notice .from { font-size:11px; color:var(--muted); }
.notice .what { font-size:14px; line-height:1.45; }

/* A route with a race on it. Pavel wanted the name to read differently at a glance, and
   the list is scanned rather than read. Gold rather than the accent cyan, which already
   means "this is a link" everywhere else on the screen. */
.race .n.raced { color:#ffd166; }
.raced { color:#ffd166; }

/* The organiser's verdict. A row of small buttons rather than a dropdown: on a phone at
   a start line, one tap beats opening a list and picking out of it, and the one that is
   already true has to be readable at a glance. */
.verdicts { display:flex; flex-wrap:wrap; gap:8px; }
.verdicts .btn { width:auto; margin:0; padding:8px 14px; font-size:13px; }
.verdicts .btn.on {
    border-color:var(--accent); color:var(--accent); background:rgba(76,201,240,.12);
}

/* Sign-in: the secondary ways in are folded away so the ordinary one is the whole screen. */
.or { text-align:center; font-size:12px; color:var(--muted); margin:14px 0 10px; }
details.card > summary { cursor:pointer; font-size:14px; font-weight:600; color:var(--muted);
  list-style:none; display:flex; align-items:center; justify-content:space-between; }
details.card > summary::after { content:"›"; color:var(--accent); font-size:20px; transition:transform .15s; }
details.card[open] > summary::after { transform:rotate(90deg); }
details.card > summary::-webkit-details-marker { display:none; }
#google-signin { display:flex; justify-content:center; }



/* ---------- Na počítači ----------------------------------------------------------

   Všechno výš je psané pro telefon a tak to má zůstat: jediný sloupec, velké dotykové
   cíle, mapa na půl obrazovky. Na monitoru to ale znamenalo 540px uprostřed a devět
   desetin plochy prázdných — a nejhůř to dopadalo na nástěnce pořadatele, což je
   shodou okolností jediná obrazovka, kterou má člověk otevřenou celý závod na notebooku.

   Zlom je 900px. Pod ním se nemění vůbec nic, takže mobil zůstává přesně jak byl. */
@media (min-width: 900px) {
    body { max-width: 1180px; }

    /* Formuláře se roztáhnout nesmí. Řádkový vstup přes celý monitor se špatně čte a
       ještě hůř vyplňuje — pole zůstávají v šířce, kde je oko přečte jedním pohledem. */
    .card input, .card select, .card textarea { max-width: 460px; }
    .card .btn { max-width: 460px; }

    .routemap { height: calc(100vh - 300px); min-height: 420px; }

    /* Dva sloupce: vlevo to, na co se kouká, vpravo to, s čím se pracuje. Hlavička jde
       přes obě. */
    .pad.two {
        display: grid;
        grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
        gap: 0 18px;
        align-items: start;

        /* dense, protože sloupce jsou přiřazené natvrdo a pořadí v markupu je dané
           telefonem. Na stránce závodů je formulář v markupu první a patří vpravo,
           seznam druhý a patří vlevo — bez dense se seznam zařadí až do dalšího řádku,
           tedy pod formulář místo vedle něj. */
        grid-auto-flow: dense;
    }
    .pad.two > .rhead,
    .pad.two > .full { grid-column: 1 / -1; }
    /* .col je obal pro sloupec, který má karet víc; stránka s jednou kartou na stranu
       si ho nemusí brát a dá .left/.right rovnou na ni. */
    /* Katalog: úzký sloupec s filtry, široký se seznamem. Opačný poměr než u nástěnky,
       kde vlevo je mapa. */
    .pad.two.aside { grid-template-columns: minmax(0, 290px) minmax(0, 1fr); }

    .pad.two > .left { grid-column: 1; }
    .pad.two > .right { grid-column: 2; }

    /* Rolovat má seznam pole, ne stránka. Na závodě s sto padesáti lidmi jinak mapa i
       okénko na zprávu odjedou nahoru pryč přesně ve chvíli, kdy pořadatel hledá, kdo se
       neozval — a to jsou tři věci, které potřebuje vidět najednou.

       Sloupec se tedy vejde do okna a je přilepený; uvnitř něj roluje jen to, co má. */
    .pad.two > .col.right {
        position: sticky;
        top: 16px;
        max-height: calc(100vh - 32px);
        display: flex;
        flex-direction: column;
    }
    /* min-height:0 není dekorace — bez něj flexová položka odmítne zmenšit pod svůj
       obsah a overflow se nikdy nespustí. */
    .pad.two .scroll { flex: 1; min-height: 0; overflow-y: auto; }
}

/* ---- Horní lišta webu ------------------------------------------------------------------
 *
 * Jen na webu. Nativní appka ji nevykresluje vůbec - telefon visí na řídítkách a obrazovka
 * je tam cennější než menu.
 *
 * Tělo stránky je sloupec široký jako telefon, i na monitoru. Lišta to musí ignorovat a
 * dosáhnout na oba okraje okna, proto ten trik se 100vw a posunem o polovinu rozdílu.
 */

.apptop {
    width: 100vw;
    margin-left: calc(-50vw + 50%);
    background: #070b16;
    border-bottom: 1px solid var(--line);
    padding-top: env(safe-area-inset-top, 0px);
}

.appwrap {
    max-width: 1180px;
    margin: 0 auto;
    padding: 0 16px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    min-height: 54px;
    flex-wrap: wrap;
}

.appbrand {
    text-decoration: none;
    font-size: 17px;
    letter-spacing: .01em;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    gap: 9px;
}

.appbrand img { border-radius: 50%; display: block; }
.appbrand .mark { color: var(--text); font-weight: 300; }
.appbrand .markb { color: var(--accent); font-weight: 700; }

.appnav { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }

.appnav a {
    color: var(--muted);
    text-decoration: none;
    font-size: 13.5px;
    white-space: nowrap;
}

.appnav a:hover { color: var(--text); }
.appnav a.on { color: var(--text); font-weight: 600; }

/* Ven, ne dovnitř. Šipka to řekne dřív, než na to někdo klikne. */
.appnav a.away {
    margin-left: 6px;
    padding-left: 18px;
    border-left: 1px solid var(--line);
    color: var(--muted);
}

.appnav a.away:hover { color: var(--accent); }
.appnav a.away .arrow { font-size: 11px; margin-left: 3px; vertical-align: super; }

@media (max-width: 560px) {
    .appwrap { min-height: 0; padding-top: 10px; padding-bottom: 10px; gap: 10px; }
    .appnav { gap: 13px; }
    .appnav a { font-size: 12.5px; }
}

/* ---- Úvodní stránka --------------------------------------------------------------------
 *
 * První verze byly dvě karty pod sebou a Zdeňkův verdikt seděl: prázdné, strojové,
 * depresivní. Říkalo to, co appka umí, a neukazovalo nic z toho.
 *
 * Tohle je pořád tmavé - venku na kole se tmavá obrazovka čte líp a je to identita appky -
 * ale ne ploché. Vzduch mezi věcmi, hero s vlastní kresbou místo cizí fotky, karty, na
 * které se dá kliknout, a patička, aby stránka někde končila.
 *
 * Jen na webu. Nativní appka tuhle stránku nevykresluje.
 */

.land {
    width: 100vw;
    margin-left: calc(-50vw + 50%);
}

.land section,
.land-foot { padding: 0 20px; }

/* ---- Hero ------------------------------------------------------------------------------ */

.hero {
    position: relative;
    overflow: hidden;
    background:
        radial-gradient(900px 320px at 18% 0%, rgba(6, 214, 160, .14), transparent 65%),
        radial-gradient(1100px 420px at 72% -10%, rgba(76, 201, 240, .30), transparent 68%),
        linear-gradient(180deg, #16244a 0%, #101a33 55%, #0b1020 100%);
    border-bottom: 1px solid var(--line);
    padding: 54px 20px 62px;
    text-align: center;
}

/* Nakreslená, ne vyfocená. Fotka by byla něčí - ty závodní jsou Pavlovy - a čára přes
   kopce je stejně to, o čem to celé je. */
.hero-line {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 180px;
    color: var(--accent);
    opacity: .16;
    pointer-events: none;
}

.hero-in { position: relative; max-width: 720px; margin: 0 auto; }

.hero-mark {
    width: 84px;
    height: 84px;
    border-radius: 50%;
    display: block;
    margin: 0 auto 18px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
}

.hero h1 {
    font-size: 38px;
    font-weight: 300;
    letter-spacing: .01em;
    margin: 0 0 12px;
    display: block;
}

.hero h1 span { color: var(--accent); font-weight: 700; }

.hero-say {
    color: var(--muted);
    font-size: 16px;
    line-height: 1.65;
    margin: 0 auto 26px;
    max-width: 540px;
}

.hero-do { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.hero-do .btn { width: auto; margin: 0; padding: 13px 26px; text-decoration: none; }

/* ---- Pruhy ----------------------------------------------------------------------------- */

.band { max-width: 1000px; margin: 0 auto; padding-top: 42px; padding-bottom: 42px; }

/* Pruh, ktery se lisi, aby stranka mela svisly rytmus a nebyla jedna plocha. */
.band.live {
    max-width: none;
    background: linear-gradient(180deg, rgba(255, 255, 255, .035), rgba(255, 255, 255, .015));
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    padding-left: 0;
    padding-right: 0;
}

.band.live > * { max-width: 1000px; margin-left: auto; margin-right: auto; padding: 0 20px; }
.band.live .rows { max-width: 1000px; }

.band-head { margin-bottom: 16px; }
.band-head h2 {
    font-size: 21px;
    color: var(--text);
    font-weight: 600;
    margin: 0 0 4px;
    display: flex;
    align-items: center;
    gap: 9px;
}
.band-say { color: var(--muted); font-size: 13.5px; }

/* ---- Dlaždice -------------------------------------------------------------------------- */

.tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 14px;
}

.tile {
    display: block;
    text-decoration: none;
    color: inherit;
    background: linear-gradient(160deg, var(--panel2) 0%, var(--panel) 70%);
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 16px;
    transition: border-color .15s, transform .15s;
}

.tile:hover { border-color: var(--accent); transform: translateY(-2px); }
.tile.quiet { background: var(--panel); }

.tile-top { display: flex; gap: 6px; margin-bottom: 10px; flex-wrap: wrap; }

.tag {
    font-size: 11px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--muted);
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 3px 9px;
}

.tag.in { color: var(--live); border-color: rgba(6, 214, 160, .5); }

.tile-name { font-size: 17px; font-weight: 600; margin-bottom: 4px; }
.tile-say { color: var(--muted); font-size: 13px; }
.tile-go { color: var(--accent); font-size: 13.5px; font-weight: 600; margin-top: 14px; }

/* ---- Řádky jezdců ---------------------------------------------------------------------- */

.rows { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }

.row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    background: var(--panel);
    border-bottom: 1px solid var(--line);
    cursor: pointer;
}

.row:last-child { border-bottom: 0; }
.row:hover { background: var(--panel2); }
.row .bib { min-width: 34px; text-align: center; font-weight: 800; color: var(--muted); }
.row .n { font-size: 15px; }
.row .d { font-size: 12.5px; color: var(--muted); }

/* ---- Prázdno, které vypadá jako záměr --------------------------------------------------- */

.blank {
    border: 1px dashed var(--line);
    border-radius: 14px;
    padding: 26px 20px;
    text-align: center;
}

.blank-say { color: var(--muted); font-size: 14px; line-height: 1.6; }
.blank .btn { width: auto; margin: 14px auto 0; display: inline-block; text-decoration: none; }

/* ---- Patička ---------------------------------------------------------------------------- */

.land-foot {
    max-width: 1000px;
    margin: 56px auto 0;
    border-top: 1px solid var(--line);
    padding-top: 30px;
    padding-bottom: calc(34px + env(safe-area-inset-bottom, 0px));
}

.foot-cols {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 26px;
}

.foot-mark { font-size: 16px; font-weight: 300; margin-bottom: 8px; }
.foot-mark span { color: var(--accent); font-weight: 700; }

.land-foot h4 {
    font-size: 12px;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--muted);
    margin: 0 0 8px;
}

.land-foot p { color: var(--muted); font-size: 13.5px; line-height: 1.65; margin: 0; }
.land-foot a { color: var(--muted); }
.land-foot a:hover { color: var(--accent); }

@media (max-width: 560px) {
    .hero { padding: 38px 18px 44px; }
    .hero h1 { font-size: 29px; }
    .hero-mark { width: 66px; height: 66px; }
    .hero-say { font-size: 14.5px; }
    .band { padding-top: 32px; }
}

/* ---- Editor webu ---------------------------------------------------------------------
   A row of controls that wraps on a phone instead of squeezing a select, a button and
   another button into 90 pixels each. */
.row-wrap { display:flex; flex-wrap:wrap; gap:10px; align-items:center; margin-top:10px; }
.row-wrap select { width:auto; min-width:120px; }
.row-wrap .btn { width:auto; }

/* A button that does something there is no way back from. Red, and not the one your
   thumb lands on first — the primary action on these screens is always something else. */
.btn.danger { background:#b3322f; color:#fff; }
.btn.danger:disabled { background:#5a2422; color:#d8b4b3; }

/* The right-hand end of a route row: the chevron, and a cross for whoever may delete it. */
.go-wrap { display:flex; align-items:center; gap:6px; }
.mini { width:auto; padding:5px 9px; font-size:14px; border-radius:8px;
        background:var(--panel2); color:var(--muted); border:1px solid var(--line); }
.mini.danger { background:#b3322f; color:#fff; border-color:#b3322f; }

/* Něco, co má člověk přečíst dřív, než klikne. Ne chyba, ne poznámka pod čarou —
   žlutý proužek, který se dá přeskočit očima jen schválně. */
.warn { margin:10px 0; padding:11px 13px; border-radius:10px; line-height:1.45;
        background:rgba(214,158,46,.12); border:1px solid rgba(214,158,46,.45); }

/* ---- Fotky z trasy -------------------------------------------------------------------
   Mřížka, která se na telefonu srovná do jednoho sloupce a na širší obrazovce vyplní. */
.photos { margin-top:18px; }
.shots { display:grid; gap:10px; grid-template-columns:repeat(auto-fill, minmax(180px, 1fr)); }
.shots figure { margin:0; background:var(--panel2); border:1px solid var(--line);
                border-radius:10px; overflow:hidden; }
.shots img { display:block; width:100%; height:150px; object-fit:cover; }
.shots figcaption { padding:6px 9px; font-size:13px; color:var(--muted); }

/* Honza, 14. 10.: small, and a tap opens one big. Above the map's own controls, which
   Leaflet puts at 1000. */
.shots.thumbs { grid-template-columns:repeat(auto-fill, minmax(84px, 1fr)); gap:6px; }
.thumb { padding:0; margin:0; border:1px solid var(--line); border-radius:8px; overflow:hidden;
         background:var(--panel2); aspect-ratio:1; cursor:zoom-in; width:100%; }
.thumb img { display:block; width:100%; height:100%; object-fit:cover; }
.photobox { position:fixed; inset:0; z-index:5000; background:rgba(0,0,0,.92);
            display:flex; flex-direction:column; align-items:center; justify-content:center;
            padding:16px; gap:12px; cursor:zoom-out; }
.photobox img { max-width:100%; max-height:calc(100% - 64px); object-fit:contain; border-radius:6px; cursor:default; }
.lb-bar { display:flex; align-items:center; gap:10px; color:#ddd; font-size:14px; cursor:default; flex-wrap:wrap; justify-content:center; }
.lb-bar .mini { min-width:40px; }
/* The race board's right column is sticky, and a sticky box keeps whatever is inside it
   under the map's controls in the left column — so the column holding an open photo goes
   up with it. */
.col:has(.photobox) { z-index:5000; }

/* ---- Značky tras na mapě --------------------------------------------------------------
   Kapka s tečkou, ne kolečko: na mapě plné zelených polí musí být poznat, že ukazuje na
   konkrétní bod. Závody jinou barvou — Pavel, 4. 10. — a k barvě patří i jiný tvar, ať to
   pozná i ten, kdo červenou a modrou nerozliší. */
.mappin { display:block; width:18px; height:18px; border-radius:50% 50% 50% 2px;
          transform:rotate(-45deg); cursor:pointer; text-decoration:none;
          background:var(--accent); border:2px solid #04121a; box-shadow:0 1px 4px rgba(0,0,0,.5); }
.mappin:hover { filter:brightness(1.25); }
.mappin.place { background:var(--live); width:14px; height:14px; }
.mappin.race { background:#ffb020; width:22px; height:22px; border-radius:50% 50% 50% 2px; }

/* Domů z Tras. Logo aplikace jako odkaz na úvodní stránku - v nativní aplikaci není
   žádná horní lišta, takže tohle je jediná cesta zpátky. */
.homemark { display: block; flex: none; line-height: 0; border-radius: 50%; }
.homemark img { display: block; border-radius: 50%; }
.homemark:active { opacity: .7; }

/* Obličej jezdce, nebo jeho iniciály. Stejně velké obojí, ať se seznam neláme podle
   toho, kdo fotku má. */
.avatar { display: block; flex: none; border-radius: 50%; object-fit: cover; }
.avatar.initials { display: flex; align-items: center; justify-content: center;
                   background: var(--line); color: var(--muted); font-weight: 700; }

/* ===== Pavel's design of 10 October: the app's tab bar, home, route cards and menu =====
   Dark navy cards with a fine cyan-tinted edge, cyan for what can be tapped. Only the
   app renders these; the web keeps its header and landing page. */

.ico { flex: none; display: inline-block; vertical-align: middle; }

/* The bar of five places along the bottom. Fixed, with the home-indicator inset below it,
   and the page leaves room for it so the last card is never under a thumb's target. */
.appbody { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
.apptabs { position: fixed; left: 0; right: 0; bottom: 0; z-index: 50; display: flex;
  max-width: 540px; margin: 0 auto;
  background: #0d1428; border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom); }
.apptabs a { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 9px 2px 10px; color: var(--muted); text-decoration: none; font-size: 11.5px; font-weight: 600; }
.apptabs a.on { color: var(--accent); }
.apptabs a.on::after { content: ""; width: 28px; height: 3px; border-radius: 3px; background: var(--accent); margin-top: 2px; }

/* Home */
.home .hhead { display: flex; align-items: center; gap: 10px; }
.home .hmark { flex: 1; font-size: 21px; font-weight: 800; }
.home .hmark span { color: var(--accent); }
.home .hq { font-size: 26px; margin-top: 14px; }
.hsay { color: var(--muted); font-size: 14px; margin-top: 2px; }
.htiles { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 12px; }
.htiles.three { grid-template-columns: 1fr 1fr 1fr; }
.htile { display: flex; flex-direction: column; gap: 4px; padding: 14px; border-radius: 14px;
  background: var(--panel); border: 1px solid #23406a; color: var(--text); text-decoration: none; }
.htile .ico { color: var(--accent); }
.htile.wide { flex-direction: row; align-items: center; gap: 12px; margin-top: 10px; }
.htile.small { align-items: center; text-align: center; padding: 12px 6px; }
/* Pavel's front page of 14. 10.: two tiles side by side, icon beside the words. */
.htile.row { flex-direction: row; align-items: center; gap: 10px; padding: 12px; }
.htile.row .htn { font-size: 15px; }
.htile.row .hts { font-size: 12px; }
/* The tracker card: sport, map, numbers, start. */
.hstart { margin-top: 12px; padding: 12px; border-radius: 14px; background: var(--panel); border: 1px solid var(--line); }
.hstart .seg { margin-top: 0; }
.hstart .seg button { display: flex; align-items: center; justify-content: center; gap: 6px; }
.hstart-map { position: relative; display: block; height: 170px; margin-top: 10px; border-radius: 12px; overflow: hidden; }
.hstart-map > *, .hstart-map .routemap { height: 100% !important; min-height: 0 !important; }
/* A picture of the map, not a map to work: the tap opens the library's. The logo and the
   attribution Mapy.com asks for stay; the zoom, rotate and layer buttons go. */
.hstart-map .maplibregl-canvas-container, .hstart-map canvas { pointer-events: none; }
.hstart-map .maplibregl-ctrl-top-left, .hstart-map .maplibregl-ctrl-top-right { display: none; }
.hstart-expand { position: absolute; top: 8px; right: 8px; height: auto !important; line-height: 0; padding: 6px; border-radius: 50%; background: var(--panel); color: var(--text); }
.hstart-nums { display: grid; grid-template-columns: repeat(3, 1fr); text-align: center; margin-top: 10px; }
.hstart-nums .v { font-weight: 800; font-size: 17px; }
.hstart-nums .k { color: var(--muted); font-size: 12px; }
.hstart-do { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 10px; }
.hstart-do .btn { margin: 0; display: flex; align-items: center; justify-content: center; gap: 6px; text-decoration: none; border-radius: 999px; }
.htn { font-weight: 700; font-size: 16px; }
.hts { color: var(--muted); font-size: 13px; }
.hsec { font-size: 19px; font-weight: 800; margin-top: 20px; display: flex; align-items: center; gap: 8px; }
.hsec.spread { justify-content: space-between; }
.hsec.spread a { color: var(--accent); font-size: 14px; font-weight: 600; text-decoration: none; }
.hrace { display: flex; gap: 12px; align-items: center; margin-top: 10px; padding: 14px; border-radius: 14px;
  background: var(--panel); border: 1px solid #23406a; }
.hrace .rshape { color: var(--accent); }
.hrace .btn, .rhead a.btn { border-radius: 10px; }
.hbadge { display: inline-block; margin-left: 6px; padding: 2px 7px; border-radius: 6px; font-size: 11px;
  font-weight: 800; text-transform: uppercase; background: #0f3d2e; color: var(--live); border: 1px solid #1d7a5a; }
.hblank { margin-top: 10px; padding: 14px; border-radius: 14px; background: var(--panel);
  border: 1px solid var(--line); color: var(--muted); font-size: 14px; display: flex; gap: 8px; align-items: center; justify-content: center; }
.hrow { margin-top: 8px; border-radius: 12px; background: var(--panel); border: 1px solid var(--line); }
.hrow .v, .rside .v { font-weight: 700; }
.hstats { display: flex; align-items: center; gap: 10px; margin-top: 10px; padding: 12px; border-radius: 14px;
  background: var(--panel); border: 1px solid #23406a; color: var(--text); text-decoration: none; }
.hstat { flex: 1; display: flex; gap: 6px; align-items: flex-start; }
.hstat .ico { color: var(--muted); margin-top: 2px; }
.hv { font-weight: 700; font-size: 14px; }
.hlinks { display: flex; justify-content: space-between; gap: 10px; margin-top: 14px; font-size: 13.5px; }
.hlinks a { color: var(--accent); text-decoration: none; }

/* Route cards: the shape, the numbers, one word for what kind of route it is. */
.applist { background: transparent !important; border: 0 !important; }
.rcard { display: flex; align-items: center; gap: 12px; padding: 12px; margin-top: 10px; border-radius: 14px;
  background: var(--panel); border: 1px solid #23406a; color: var(--text); text-decoration: none; cursor: pointer; }
.rcard.quiet { border-color: var(--line); }
.rcard .rshape { flex: none; color: var(--accent); background: #0d1428; border-radius: 10px; padding: 4px; }
.rcard .n { font-weight: 700; font-size: 17px; }
.rcard .n.raced { color: #ffd166; }
.rcard .d { color: var(--muted); font-size: 13.5px; margin-top: 3px; display: flex; align-items: center; gap: 4px; }
.rside { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
.rbadge { display: inline-flex; align-items: center; gap: 4px; padding: 4px 8px; border-radius: 8px;
  font-size: 12px; font-weight: 600; color: var(--accent); border: 1px solid #23406a; white-space: nowrap; }
.rbadge.race { color: #ffd166; border-color: #8a6d1c; }

/* A switch rather than a checkbox, as in the design: on/off, readable at a glance. */
/* The DoKola! showcase on the front page: gold, the main offer. Below it the other
   virtual races in turquoise, so the two are never mistaken for each other. */
.hgold { display: block; margin-top: 14px; padding: 14px; border-radius: 16px; text-decoration: none;
  background: linear-gradient(160deg, #2a2210 0%, #171a26 70%); border: 1.5px solid #d4a52c; color: var(--text); }
.hgold:visited { color: var(--text); }
.hgold-head { display: flex; align-items: center; justify-content: space-between; color: #f1c84b;
  font-weight: 800; font-size: 15px; letter-spacing: .02em; }
.hgold-body { display: flex; gap: 14px; align-items: center; margin-top: 10px; }
.hgold-name { font-size: 20px; font-weight: 800; }
.hgold-say { font-size: 14px; color: #f3e3b0; margin: 4px 0 6px; line-height: 1.35; }
.btn.gold, a .btn.gold { display: block; text-align: center; margin-top: 12px; background: #f1c84b; color: #2a1e00;
  border-radius: 10px; }
.hbadge.gold { background: #3a2c08; color: #f1c84b; border-color: #8a6d1c; }
.hrace.teal { background: #0e2a33; border-color: #1f8aa5; text-decoration: none; color: var(--text); }
.hrace.teal:visited { color: var(--text); }
.hrace.teal .rshape { color: #6fe3f5; }
.rcard.teal { background: #0e2a33; border-color: #1f8aa5; }
.btn.teal, a .btn.teal { display: inline-block; width: auto; margin-top: 10px; padding: 8px 16px; font-size: 14px;
  background: #3fc8e4; color: #04212b; border-radius: 10px; }

/* The DoKola! banner on the front page, after Pavel's picture of 10 October: bright
   turquoise, the mark on the left, the offer on the right and a medal drawn faintly behind. */
.hbanner, .hbanner:visited { position: relative; overflow: hidden; display: flex; align-items: center; gap: 10px;
  margin-top: 16px; padding: 14px 12px; border-radius: 14px; text-decoration: none; color: #04212b;
  background: linear-gradient(120deg, #6fe3f5 0%, #3fc8e4 55%, #2bb3d3 100%); border: 1.5px solid #c9f6ff; }
.hbanner-logo { flex: 0 0 34%; text-align: center; z-index: 1; }
.hbanner-mark { font-size: 24px; font-weight: 900; font-style: italic; letter-spacing: .02em; color: #fff;
  text-shadow: 0 1px 0 #1b8fab, 0 0 8px rgba(4, 33, 43, .25); }
.hbanner-sub { font-size: 9px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: #0b5e72; }
.hbanner-text { flex: 1; z-index: 1; }
.hbanner-h { font-size: 17px; font-weight: 900; line-height: 1.1; }
.hbanner-say { font-size: 11.5px; margin-top: 4px; line-height: 1.3; }
.hbanner-btn { display: inline-block; margin-top: 8px; padding: 5px 12px; border-radius: 999px;
  background: #0b2530; color: #fff; font-size: 12px; font-weight: 700; }
.hbanner-medal { position: absolute; right: -22px; top: -6px; width: 92px; height: 115px; fill: none;
  stroke: #e8fbff; stroke-width: 2.5; opacity: .3; }

/* A race's flyer: a preview that opens full screen, above the map's controls. */
.flyer { display:block; width:100%; border-radius:10px; cursor:zoom-in; }
.lightbox { position:fixed; inset:0; z-index:5000; background:rgba(0,0,0,.92); overflow:auto;
  display:flex; align-items:flex-start; justify-content:center; padding:env(safe-area-inset-top) 0 20px; }
.lightbox img { width:100%; max-width:1200px; height:auto; touch-action:pinch-zoom; }

/* A page of the site in blocks. Pavel, 10. 10.: headings that stand out and room between
   paragraphs, so it reads on a phone. */
.doc h1 { font-size: 26px; line-height: 1.2; margin: 4px 0 12px; }
.doc .docintro { font-size: 16.5px; line-height: 1.6; color: var(--text); }
.doc .docintro p, .doc .docblock p { margin: 0 0 12px; }
.doc .docblock { margin-top: 14px; padding: 16px 16px 6px; border-radius: 14px; background: var(--panel);
  border: 1px solid var(--line); line-height: 1.6; font-size: 15.5px; }
.doc .docblock h2 { margin: 0 0 10px; font-size: 19px; color: var(--accent); }
.doc .docblock ul, .doc .docblock ol { margin: 0 0 12px; padding-left: 20px; }
.doc .docblock li { margin-bottom: 6px; }
.doc a { color: var(--accent); }
.doc table { border-collapse: collapse; width: 100%; margin-bottom: 12px; font-size: 14px; }
.doc td, .doc th { border-bottom: 1px solid var(--line); padding: 6px 4px; text-align: left; }
.editblock textarea { width: 100%; font: inherit; font-size: 15px; line-height: 1.5; }
.editbtns { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }

/* The banner at the foot of the app, to the race's own site: the organiser's picture, or
   until there is one the same invitation in words. */
.fbanner { display: block; margin-top: 18px; border-radius: 12px; overflow: hidden; text-decoration: none;
  border: 1px solid #1f8aa5; }
.fbanner img { display: block; width: 100%; height: auto; }
.fbanner.words { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; padding: 12px 14px;
  background: linear-gradient(100deg, #06202b 0%, #0b3a4a 60%, #135a6e 100%); color: #e8fbff; }
.fbanner .fb-mark { font-weight: 900; font-style: italic; font-size: 18px; }
.fbanner .fb-date { font-weight: 800; font-size: 18px; color: #6fe3f5; }
.fbanner .fb-say { flex-basis: 100%; font-size: 13px; color: #b9e9f3; }
.land-foot .fbanner { margin: 0 0 18px; }

/* "Jak se jelo?" after a race: answers to tap. */
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 6px; }
.pick { width: auto; margin: 0; padding: 7px 12px; border-radius: 999px; font-size: 14px;
  background: var(--panel2); border: 1px solid var(--line); color: var(--text); }
.pick.on { background: #0f2a3d; border-color: var(--accent); color: var(--accent); font-weight: 700; }
.report textarea { width: 100%; font: inherit; }

/* What is waiting for an administrator: only there when something is. */
.card.waiting { border-color: #d4a52c; background: #2a2210; }
.card.waiting .k { color: #f1c84b; font-weight: 800; }
.card.waiting .mrow { padding: 10px 0; }
.card.waiting .dot { width: 8px; height: 8px; border-radius: 50%; background: #f1c84b; }

/* A finisher's place in the first column of the board. */
.race .bib.place { color: var(--live); }

/* An invitation to a private challenge, waiting for an answer. */
.card.invite { border-color: var(--accent); background: #0f2a3d; }

/* The courses of a race as cards to tap, the chosen one lit. */
.courses { display: flex; flex-direction: column; gap: 8px; }
.course { display: flex; align-items: center; gap: 12px; width: 100%; padding: 10px 12px; border-radius: 12px;
  background: var(--panel2); border: 1px solid var(--line); color: var(--text); }
.course .rshape { color: var(--muted); }
.course.on { border-color: var(--accent); background: #0f2a3d; }
.course.on .rshape, .course .tick { color: var(--accent); font-weight: 800; }
.course .n { font-weight: 700; }
.course .d { color: var(--muted); font-size: 13px; }

.switch { display: inline-flex !important; align-items: center; gap: 10px; margin: 0 !important;
  font-size: 15px !important; color: var(--text) !important; cursor: pointer; }
.switch input { display: none; }
.switch .knob { width: 44px; height: 26px; border-radius: 13px; background: var(--panel2); border: 1px solid var(--line);
  position: relative; transition: background .15s; }
.switch .knob::after { content: ""; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%;
  background: #cfd8ee; transition: transform .15s; }
.switch input:checked + .knob { background: var(--accent); }
.switch input:checked + .knob::after { transform: translateX(18px); background: #04121a; }

/* Profil a nabídka */
.mcard { display: flex; align-items: center; gap: 14px; padding: 14px; border-radius: 14px;
  background: var(--panel); border: 1px solid #23406a; color: var(--text); text-decoration: none; }
.mname { font-size: 20px; font-weight: 800; }
.msay { color: var(--muted); font-size: 13px; margin-top: 2px; }
.mhead { margin: 18px 4px 6px; font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.mhead.in { margin: 4px 0 6px; color: #ffd166; }
.mlist { display: block; border-radius: 14px; background: var(--panel); border: 1px solid var(--line);
  overflow: hidden; text-decoration: none; }
.mlist.admin { margin-top: 18px; padding: 8px 0 4px; border-color: #b8901f; }
.mlist.admin .mhead.in { padding: 0 14px; }
.mlist.danger { margin-top: 14px; border-color: #7a2a2a; }
.mlist.danger .mrow { color: #ff6b6b; }
.mrow { display: flex; align-items: center; gap: 12px; padding: 13px 14px; color: var(--text); text-decoration: none; font-size: 16px; }
.mrow + .mrow { border-top: 1px solid var(--line); }
.mrow > .ico:first-child { color: var(--accent); }
.mrow > .ico:last-child { color: var(--muted); }
.pad-in { padding: 6px 14px 4px; }

/* The cookie bar. Above everything at the bottom, clear of the iPhone home indicator. */
.cookiebar { position:fixed; left:0; right:0; bottom:0; z-index:2000; max-width:540px; margin:0 auto;
  background:var(--panel); border-top:1px solid var(--line);
  padding:12px 14px calc(12px + env(safe-area-inset-bottom));
  display:flex; flex-wrap:wrap; gap:10px; align-items:center; font-size:14px; }
.cookiebar-text { flex:1 1 260px; color:var(--text); line-height:1.4; }
.cookiebar-text a { color:var(--accent); }
.cookiebar-buttons { display:flex; gap:8px; }
.cookiebar-buttons .mini { min-width:100px; padding:9px 12px; }

/* Partners of DoKola! (Pavel, 16. 10.): their logos in a grid, each a link to their site. */
.partners { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; }
.partner { display: flex; align-items: center; justify-content: center; min-height: 90px; padding: 12px;
           border-radius: 12px; background: #ffffff; color: #1d1d1b; font-weight: 700; text-align: center; }
.partner img { max-width: 100%; max-height: 70px; object-fit: contain; }
