:root {
  color-scheme: dark;
  --bg: #0d0e0f;
  --card-bg: #141517;
  --text: #ececec;
  --muted: #9ca0a4;
  --accent: #1f6f50;
  --accent-text: #ffffff;
  --border: #2b2d30;
  --field-border: #6b6f73;
  --error: #ff7a6b;
  /* Badge-only colours (stylesheet corrections round): the "Moje deble"
     section label's own background, distinct from --accent since that one
     is reserved for the matched-status badge. White text on this is
     5.42:1; this colour on the card background is 3.37:1. */
  --section-label-bg: #2b6cb0;
  /* The rejected/not-attending status badge's background. As plain text on
     the card this was 1.31:1 -- unusable; white text on this fill is
     13.94:1. */
  --status-other-bg: #5b0d09;
  /* Three-tone stylesheet round: PENDING gets its own badge colour again,
     shared by both directions -- "oczekujące" on a sent invitation and
     "zaprasza" on a received one are both this orange now, distinct from
     the red REJECTED/NOT_ATTENDING now stand alone in. */
  --status-pending-bg: #94520c;
  /* Moje deble row-actions round: Zatwierdź's own text colour. Neither
     existing green (--accent, 3.00:1 as plain text on the card) nor the
     oxblood red (--status-other-bg, 1.31:1 as plain text) clears the
     4.5:1 text-contrast minimum -- both stay filled-badge-only colours.
     This green is 7.53:1 as plain text on the card. */
  --action-accept: #3cbb88;
}

/* Light theme override (theme-toggle round): :root above is untouched --
   it stays the dark theme, byte-for-byte, exactly as it always was. This
   is the only place any of its custom properties are ever overridden.
   Exactly these seven change; --accent, --accent-text, --field-border,
   --section-label-bg, --status-other-bg and --status-pending-bg are
   deliberately NOT overridden here -- all four badge fills carry white
   text, so their contrast is independent of the page background behind
   them (6.09, 6.05, 13.94, 5.42:1, all unchanged from the dark theme).
   Light-mode ratios on --card-bg: text 16.72:1, muted 6.07:1,
   action-accept 5.72:1, error 6.14:1, field-border 4.76:1. */
[data-theme="light"] {
  color-scheme: light;
  --bg: #eceded;
  --card-bg: #f7f8f7;
  --border: #d6d8d6;
  --text: #16181a;
  --muted: #5a5f63;
  --action-accept: #1f6f50;
  --error: #b3261e;
}

@font-face {
  font-family: "Lato";
  font-weight: 400;
  src: url("/static/fonts/lato-regular.woff2") format("woff2");
  font-display: swap;
}

@font-face {
  font-family: "Lato";
  font-weight: 700;
  src: url("/static/fonts/lato-bold.woff2") format("woff2");
  font-display: swap;
}

@font-face {
  font-family: "Lato";
  font-weight: 900;
  src: url("/static/fonts/lato-black.woff2") format("woff2");
  font-display: swap;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "Lato", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 19px;
  line-height: 1.5;
}

/* Invariant: no link in this app carries any text decoration, on any page, in any state. */
a {
  text-decoration: none;
}

.page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Content starts near the top, not vertically centered in the viewport --
     centering here is what left roughly half a screen of blank space above
     the breadcrumb/card on short pages (e.g. the confirmation screen). */
  justify-content: flex-start;
  padding: 24px 16px;
}

.card {
  width: 100%;
  max-width: 420px;
  background: var(--card-bg);
  border: 1px solid var(--border);
  padding: 28px 24px;
}

/* home.html's temporary invitation blocks (build order step 6) are a
   second and third .card on the same page as the greeting card -- without
   this they'd sit flush against each other. */
.card + .card {
  margin-top: 16px;
}

/* A generic fix, not a one-off: any element's own trailing margin plus
   .card's own bottom padding double up into an oversized gap under the
   card's last child (found under the first /my-account card's share
   link, a <p> carrying the tag-wide `p { margin: 0 0 16px; }`). Every
   card has this problem the moment its last child carries a bottom
   margin, so this is scoped to *:last-child generally rather than to
   that one paragraph. */
.card > *:last-child {
  margin-bottom: 0;
}

/* landing.html's tagline block (visual overhaul): plain text, not a
   card -- the wordmark is already in the site header, so this is prose,
   not a boxed unit. Same max-width as .card so it still lines up. */
.intro {
  width: 100%;
  max-width: 420px;
  margin-bottom: 16px;
}

h1 {
  font-size: 1.15rem;
  font-weight: 900;
  margin: 0 0 12px;
}

h2 {
  font-size: 1.15rem;
  margin: 0 0 12px;
}

p {
  margin: 0 0 16px;
  color: var(--muted);
}

label {
  display: block;
  font-weight: 600;
  margin-bottom: 8px;
}

input[type="email"],
input[type="text"] {
  width: 100%;
  padding: 14px;
  font-size: 1.1rem;
  border: 1px solid var(--field-border);
  margin-bottom: 16px;
}

button,
.button {
  display: inline-block;
  width: auto;
  padding: 15px 28px;
  font-size: 1.1rem;
  font-weight: 600;
  text-align: center;
  color: var(--accent-text);
  background: var(--accent);
  border: none;
  cursor: pointer;
  text-decoration: none;
}

/* Category buttons (search_category.html): scaled down to .section-label's
   own size (same font-size, padding and weight) -- the primary .button
   shape everywhere else (/my-account, the consent screens, /invite) must
   stay full-sized, so this is a modifier applied only on that one page's
   links, never a change to .button itself. Colour is untouched -- still
   var(--accent) / var(--accent-text) via the base .button rule. Height
   (font-size + vertical padding) is correct as shipped and stays put --
   only the horizontal padding grows here, to widen the tap target without
   changing how tall the button reads. */
.button-category {
  font-size: 0.75rem;
  font-weight: 700;
  padding: 4px 20px;
}

/* Wraps search_category.html's three category links so a row that wraps
   onto a second line still gets a consistent gap on both axes -- the
   general form/.button adjacent-sibling margin rule below only ever adds
   vertical space, which left the buttons touching edge-to-edge when they
   sat side by side on one line. `gap` supplies both column- and row-gap
   from one declaration, so nothing further is needed in either
   direction. These stay well under Apple's 44px touch-target guidance
   (~30px tall); WCAG 2.2's target-size success criterion treats spacing
   between adjacent small targets as mitigating mis-taps, which is exactly
   what this gap is for. */
.category-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* The general .button + .button spacing rule below exists for buttons
   stacked full-width down a page -- inside the flex row above, `gap`
   already supplies that spacing, so the sibling rule is switched off here
   to avoid stacking an extra 12px on top of it. */
.category-buttons .button + .button {
  margin-top: 0;
}

/* Stacked buttons (including one-button <form>s, which render as full-width
   buttons themselves) need a visible gap or they read as one control -- easy
   to mis-tap on a phone. A general rule rather than a one-off, since later
   pages will keep pairing buttons this way. */
form + form,
form + button,
form + .button,
button + form,
button + button,
button + .button,
.button + form,
.button + button,
.button + .button {
  margin-top: 12px;
}

.error {
  color: var(--error);
  font-weight: 600;
}

/* Standard clip-rect pattern -- present in the DOM and in the accessibility
   tree (unlike display:none/visibility:hidden, both of which remove an
   element from it), but invisible on screen. Used on /search/confirm's
   submit button: implicit form submission from the phone keyboard's return
   key is only guaranteed with a real submit button present, but the
   operator asked for no visible button except "Wybierz inną kategorię". */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Site header (base.html): a logo mark plus wordmark on every page,
   deliberately never a link -- see base.html's own comment. Same
   max-width as .card and .breadcrumbs so it lines up with them. */
.site-header {
  width: 100%;
  max-width: 420px;
  display: flex;
  align-items: center;
  gap: 10px;
  /* Theme-toggle round: this used to be 24px, matching .card's own
     horizontal padding, so .site-user's right edge lined up with a card's
     content edge below it. It can't stay -- the toggle (.site-theme,
     below) is now the header's last child and sits at the content edge
     itself, providing its own visual terminus, and logo + wordmark +
     "MOJE KONTO" badge + toggle overflows a 360px viewport by roughly
     17px with the old 24px still in place. */
  padding-right: 0;
  padding-bottom: 16px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--border);
}

.site-wordmark {
  font-size: 1.15rem;
  font-weight: 700;
}

/* Wraps both the logo image and the wordmark in one link to /my-account
   (header-footer-ui-changes round) -- the image carries alt="" (decorative),
   so an anchor around it alone would have no accessible name; wrapping both
   gives the link the name "CourtDuo". Same flex row and gap the two
   children already used as direct .site-header flex items, now scoped to
   this wrapper instead, plus color: inherit so the wordmark keeps its
   normal text colour rather than the browser's default link blue --
   text-decoration is already handled by the global `a { text-decoration:
   none; }` rule. Gated in base.html on the same condition that already
   decides whether the "Moje konto" badge renders as a link
   (hide_account_link, plus first_name meaning this is /my-account itself)
   rather than a second flag. */
.site-logo-link {
  display: flex;
  align-items: center;
  gap: 10px;
  color: inherit;
}

/* The logged-in player's first name (base.html, /my-account only -- see
   app/routes/auth.py::home): pushed to the header's right edge via its own
   margin-left rather than a justify-content change, so the logo+wordmark
   stay left-aligned exactly as before on every page that doesn't pass
   first_name. Same size, weight and colour as a Moje deble row's
   tournament line (.deble-row-tournament) -- both are quiet secondary
   text -- reusing 0.85rem rather than inventing a new value, since that's
   already this file's quiet-text size (.breadcrumbs, .link-button). */
.site-user {
  margin-left: auto;
  font-size: 0.85rem;
  font-weight: 400;
  color: var(--muted);
  /* header-footer-ui-changes round: capitals read as a name badge rather
     than a sentence fragment. Uppercase alone sets too tight at this size,
     hence the small letter-spacing -- size, weight and colour unchanged. */
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* "Moje konto" header badge (base.html): shown in the same header slot as
   .site-user, on every page by default, except when the page has
   first_name to show instead (base.html's own {% elif %} -- never both at
   once) or explicitly opts out via hide_account_link (the parent-facing
   consent screens, and every screen with no session at all -- see
   base.html's own comment). Same badge shape and colour as
   .section-label, reusing --section-label-bg rather than a second
   declaration of that hex, pushed to the header's right edge the same way
   .site-user is. */
.site-account-link {
  margin-left: auto;
  display: inline-block;
  background: var(--section-label-bg);
  color: var(--accent-text);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.75rem;
  font-weight: 700;
  padding: 4px 8px;
  /* Theme-toggle round: the header row is fuller now (logo, wordmark,
     badge, toggle) -- this keeps the badge from wrapping onto two lines
     on a narrow screen. */
  white-space: nowrap;
}

/* Theme toggle (base.html): the last child of .site-header, on every
   page. margin-left: auto is needed on a page with hide_account_link set
   and no first_name (the parent-facing consent screens) -- nothing else
   in the row pushes right there. Below, when a name or badge is already
   doing that job, auto is replaced (not zeroed) with a fixed 14px: a
   positive margin still cancels the auto, so free space can't split and
   shove the name/badge toward the middle instead of the header's far
   edge, while still opening up visible separation from the toggle. With
   .site-header's own 10px gap, that separation is 24px -- not a new
   number, the same 24px .card already uses for its own horizontal
   padding. margin-top: 0 defends against the browser's default <form>
   margin, the same reason .page-footer > * zeroes it above. */
.site-theme {
  margin-left: auto;
  margin-top: 0;
}

.site-user + .site-theme,
.site-account-link + .site-theme {
  margin-left: 14px;
}

/* Overrides the global `button` rule above (solid --accent fill, 15px
   28px padding) -- this is a small, quiet icon control, not a primary
   action. No rounded corners anywhere in this file (test_style_css.py's
   own invariant), so this stays a plain square. */
.site-theme-button {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  padding: 0;
  background: none;
  border: 1px solid var(--field-border);
  color: var(--muted);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

/* 20px is still under the 24px WCAG 2.2 target minimum and far under
   Apple's 44pt guidance, and the users are children tapping one-handed.
   This invisible ::after expands the tap area to 36px (-8px inset on all
   sides) without growing the visible control -- 2px of clearance is kept
   against .site-account-link's 10px gap so this can't steal its taps. No
   background and no z-index: it must stay invisible and must not layer
   above anything. */
.site-theme-button::after {
  content: "";
  position: absolute;
  inset: -8px;
}

/* Breadcrumb trail (base.html): quiet, sits directly above the card that
   holds the page heading. Same max-width as .card so it lines up with it. */
.breadcrumbs {
  width: 100%;
  max-width: 420px;
  margin: 0 0 10px;
  font-size: 0.85rem;
  color: var(--muted);
}

.breadcrumbs a {
  color: var(--muted);
}

.breadcrumbs [aria-current="page"] {
  color: var(--text);
}

.breadcrumb-sep {
  margin: 0 6px;
}

/* Logout footer (base.html): present on every logged-in page, deliberately
   quiet and secondary -- CHANGE 2 moved it here off /my-account. A row,
   not a stack: the privacy link and the logout form sit side by side
   rather than on separate lines. base.html's rendered markup is exactly
   `<footer class="page-footer"><a class="link-button" href="/privacy">
   ...</a><form method="post" action="/logout">...</form></footer>` --
   no wrapper element around either child, only whitespace text nodes, so
   there is nothing here for a stray block-level wrapper to explain.
   `form` needs no `display` rule of its own -- a flex container already
   lays out any block-level child (the <form>) as a flex item; `flex-wrap`
   and the zeroed child margins below exist so neither child's own box
   (a browser default margin on <form> in particular) can push a wrap. */
.page-footer {
  width: 100%;
  max-width: 420px;
  margin-top: 16px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: 12px;
  /* header-footer-ui-changes round: without this the footer's own box
     starts at .page's edge, flush with the *outer* edge of the card above
     it rather than the card's *content* edge -- same 24px .card's own
     horizontal padding already uses, and the same number .site-header's
     own padding-right reuses for the identical reason (see that rule's
     comment). Matches on both sides so the last link clears the right
     edge too, not just the first one lining up on the left. */
  padding: 0 24px;
}

.page-footer > * {
  margin: 0;
}

/* .link-button's own 10px 8px padding leaves the privacy link sitting 8px
   in from the card edge above it once the footer is left-aligned -- zero
   the left padding here only, not on .link-button itself, since that same
   class is also the "Kopiuj link" control (partner_confirm.html,
   invite.html), which must keep its current padding. */
.page-footer .link-button {
  padding-left: 0;
}

/* Also used by the "Kopiuj link" control (partner_confirm.html, invite.html)
   -- CLAUDE.md "Pre-invitation checks": demoted from a full-width button to
   quiet text so it doesn't carry the same visual weight as the WhatsApp
   share button above it. Kept as `inline-block`, not `inline`: an inline
   box's vertical margin has no layout effect, which is exactly what made
   the un-demoted three-button stack overlap -- `inline-block` lets the
   existing button/.button adjacent-sibling spacing rule below apply here
   too, rather than a one-off rule for this element. */
/* The iOS Share glyph inside the Add-to-Home-Screen banner's first step
   (CLAUDE.md "PWA requirements"): sized to the surrounding text via `1em`
   on the element itself, so this rule only needs to nudge its baseline to
   sit level with the text around it. */
.ios-share-glyph {
  vertical-align: -0.15em;
}

.link-button,
.js-copy {
  display: inline-block;
  width: auto;
  padding: 10px 8px;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 400;
  cursor: pointer;
}

/* General tappable list (CHANGE 3): a card-background row per item instead
   of a stack of solid buttons. Reused as-is by "Moje deble" (step 7) --
   not a one-off for the tournament results page. */
.list {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
  border: 1px solid var(--border);
  overflow: hidden;
}

.list li + li {
  border-top: 1px solid var(--border);
}

.list-item {
  display: block;
  width: 100%;
  padding: 16px 14px;
  background: var(--card-bg);
  color: var(--text);
  font-size: 1.05rem;
  font-weight: 400;
  text-align: left;
  text-decoration: none;
}

.list-item:hover,
.list-item:focus {
  background: var(--bg);
}

.list-item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* Tournament results (search_results.html) only -- a bulleted list rather
   than the boxed-row look .list carries everywhere else (Moje deble
   included, which keeps its approved boxed appearance unchanged). Markup
   stays exactly <ul class="list list-bullets"><li><a class="list-item">;
   this modifier only ever touches presentation, never structure. */
.list-bullets {
  border: none;
}

.list-bullets li + li {
  border-top: none;
}

.list-bullets .list-item {
  position: relative;
  padding-left: 34px;
}

/* A small solid square, never a circle -- CLAUDE.md's no-rounded-corners
   invariant. Positioned to sit level with the first line of the row's
   text; the indent above (padding-left: 34px) keeps the text clear of it. */
.list-bullets .list-item::before {
  content: "";
  position: absolute;
  left: 14px;
  top: 24px;
  width: 8px;
  height: 8px;
  background: var(--accent);
}

/* A .list row that holds more than one tappable thing (text plus one or
   more forms/buttons) -- not .list-item, which is for a single <a> that
   fills the whole row. Introduced for home.html's temporary invitation
   block (build order step 6); "Moje deble" (step 7) may reuse it. */
.list-row {
  padding: 16px 14px;
}

.list-row p {
  margin: 0 0 8px;
  color: var(--text);
}

/* Scoped, not deleted (row-actions round): still spaces any other
   .list-row content that isn't wrapped in .deble-row-actions below, but
   must not reach a button this container now lays out itself via `gap` --
   an unscoped margin-top here fights .deble-row-actions's
   align-items: center and reintroduces exactly the forced line-break that
   container exists to fix. */
.list-row .button:not(.deble-row-actions *),
.list-row button:not(.deble-row-actions *) {
  margin-top: 8px;
}

/* Moje deble row actions (row-actions round): rendered markup is
   `<div class="list-row">...<p class="deble-row-tournament">...</p>
   <div class="deble-row-actions">{% if can_accept %}<a class="link-button
   link-button-accept">...</a>{% endif %}{% if can_reject %}<form>
   <button class="link-button link-button-reject">...</button></form>
   {% endif %}...</div></div>` -- Zatwierdź is an `<a>`, Odrzuć a `<form>`
   containing a `<button>`, and a `<form>` is block-level by default, which
   is what forced the two onto separate lines (not the margin-top rule
   above, which never touched the `<a>` at all -- it isn't `.button` or
   `button`). This container is the actual fix: a flex row with `gap`
   supplying the space the old margin-top rule used to, and every direct
   child zeroed so neither a `<form>`'s own box nor the general
   `form + form` / `.button + form` adjacent-sibling spacing rule above
   (higher element-selector specificity, but still loses to this
   class-scoped `> *` rule) can reintroduce a break. flex-wrap keeps a
   long pair from overflowing on a narrow phone; a single-action row
   (withdraw, release) renders inside the same container with nothing
   else to align against. */
.deble-row-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}

.deble-row-actions > * {
  margin: 0;
}

/* Zatwierdź / Odrzuć (row-actions round): the only two row actions that
   get their own colour -- withdraw and release stay the plain muted
   .link-button colour. See --action-accept above for why this can't
   reuse --accent, and CLAUDE.md's existing --error (7.18:1 as plain text
   on the card, already used for .error) for why Odrzuć needed no new
   variable of its own. */
.link-button-accept {
  color: var(--action-accept);
}

.link-button-reject {
  color: var(--error);
}

/* account_delete.html's submit button (account-delete-styling round):
   demoted from a full-width .button to quiet text, matching every other
   form action on this page ("Wróć do konta" is already .link-button) --
   but this one action is irreversible and sits directly above that escape
   link, so colour is the only thing left distinguishing them. Reuses the
   same var(--error) .link-button-reject already uses for Odrzuć (7.18:1
   on the card), never --status-other-bg (1.31:1 as plain text --
   unreadable) and never the muted default, which would make the two
   actions indistinguishable. A separate class rather than reusing
   .link-button-reject directly: that class's own comment above scopes it
   to the two Moje deble row actions specifically. */
.link-button-delete {
  color: var(--error);
}

/* "Moje deble" (CLAUDE.md "Moje deble") section heading, restyled as a
   filled badge rather than a plain heading -- kept an <h2> (screen readers
   rely on it), just given this class. Its own background rather than
   --accent (that one is reserved for the matched status-label below, so
   the two badges read as different things): white text on
   --section-label-bg is 5.42:1, and --section-label-bg is 3.37:1 against
   the card. */
.section-label {
  display: inline-block;
  background: var(--section-label-bg);
  color: var(--accent-text);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.75rem;
  font-weight: 700;
  padding: 4px 8px;
}

/* Each Moje deble row's head line: the partner's name on the left, the
   status label at the right-hand end. flex-wrap so a long label (e.g.
   "WYSŁANE (OCZEKUJĄCE)") wraps onto its own line instead of crushing the
   name rather than overflowing the row. */
.deble-row-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}

.list-row .deble-row-name {
  margin: 0;
}

.list-row .deble-row-tournament {
  margin: 0 0 8px;
  font-size: 0.85rem;
  color: var(--muted);
}

/* A row's status, as a filled badge (never a circle -- CLAUDE.md's
   no-rounded-corners invariant) instead of the coloured emoji this
   replaces. The operator's picked rejected/not-attending colour
   (#5b0d09) is 1.31:1 as plain text on the card -- unusable; as a filled
   background with white text it is 13.94:1. Both this and the matched
   variant are the same shape, differing only in background -- the
   ::before square this used to carry is gone, since the filled block
   itself is now the colour cue and a square inside it would be noise. */
.status-label {
  display: inline-block;
  background: var(--accent);
  color: var(--accent-text);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.7rem;
  font-weight: 700;
  white-space: nowrap;
  padding: 4px 8px;
}

/* 6.09:1 white on --accent. */
.status-label-matched {
  background: var(--accent);
}

/* Three-tone stylesheet round: PENDING is orange again, in both
   directions -- CLAUDE.md "Moje deble". White text on #94520c is ~7.7:1. */
.status-label-pending {
  background: var(--status-pending-bg);
}

/* 13.94:1 white on --status-other-bg -- REJECTED and NOT_ATTENDING share
   this colour; PENDING moved to its own tone above. */
.status-label-other {
  background: var(--status-other-bg);
}

/* A single-field form's submit control: a small quiet arrow at the input's
   right edge instead of a full-width "Szukaj" button -- CLAUDE.md
   "Navigation and presentation": the keyboard return key still submits,
   this is an addition for a tap, not a replacement. /search/confirm's
   partner-name field is the first use; reusable wherever else a
   single-field form needs it. */
.input-with-arrow {
  position: relative;
  margin-bottom: 16px;
}

.input-with-arrow input[type="text"] {
  margin-bottom: 0;
  padding-right: 52px;
}

.input-with-arrow-submit {
  position: absolute;
  top: 50%;
  right: 2px;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}

.input-with-arrow-submit:hover {
  color: var(--text);
}

.input-with-arrow-submit:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.input-with-arrow-glyph::before {
  content: "\2192";
}

/* /privacy (CLAUDE.md "The privacy policy page"): the operator-approved
   policy text, reused as long-form prose rather than short UI copy.
   Scoped under .privacy-body rather than bare tag selectors (h2, ul, hr)
   so it can never leak into other .card content elsewhere -- .list, the
   general tappable-row list used on the tournament results and "Moje
   deble" screens, is a <ul> that also lives inside a .card. */
.privacy-body h3 {
  font-size: 1rem;
  margin: 0 0 12px;
}

.privacy-body ul,
.privacy-body ol {
  margin: 0 0 16px;
  padding-left: 20px;
  color: var(--muted);
}

.privacy-body li {
  margin-bottom: 6px;
}

.privacy-body hr {
  border: none;
  border-top: 1px solid var(--border);
  margin: 24px 0;
}

.privacy-body .privacy-updated {
  margin-top: -4px;
}

/* A two- or three-column table stacked as label/value pairs instead --
   CLAUDE.md: "must be readable on a 380px phone," and a sideways-scrolling
   <table> is explicitly ruled out. */
.privacy-body .dl-table {
  margin: 0 0 16px;
  border-top: 1px solid var(--border);
}

.privacy-body .dl-row {
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}

.privacy-body .dl-row dt {
  font-weight: 600;
  color: var(--text);
}

.privacy-body .dl-row dd {
  margin: 4px 0 0;
  color: var(--muted);
}

.privacy-body .dl-label {
  font-weight: 600;
  color: var(--text);
}
