/* ============================================================ modern.css
 *
 * A layer on top of tamitos.css and public.css, never a replacement.
 *
 * Two things live here and they are here together because they arrived
 * together: the real wordmark, and the frosted surfaces that make the pages
 * look like something built this year rather than in 2016.
 *
 * Additive on purpose. Those two files are 22 KB and 10 KB of working layout;
 * editing them to change a background is how a stylesheet becomes a thing
 * nobody dares touch. Everything below either styles a class that did not
 * exist before, or overrides exactly one property of one that did.
 * ==================================================================== */

/* --------------------------------------------------- no sideways drag

   On a phone the page could be dragged left and right by about 24px, which
   is the tell that makes a site feel thrown together: everything slides, the
   fixed header slides with it, and there is a strip of empty white on the
   right.

   Nothing was actually too wide. The cause was `.hero::before`, the ambient
   blue glow, which is placed at `right: -6%` with a width of `46vw` — 179px
   on a 390px screen, so its right edge lands at 413 and the document is 414
   wide. It is decoration and it is meant to bleed; what it must not do is
   make the page scrollable.

   `clip` rather than `hidden`, and the difference matters here. `overflow-x:
   hidden` turns the element into a scroll container, and a scroll container
   is where `position: sticky` stops working — the nav on every one of these
   pages is sticky. `clip` cuts the overflow without creating one.

   Set on both, because which of the two becomes the viewport's scrolling box
   is not something a stylesheet should have an opinion about. */
html,
body { overflow-x: clip; }

/* ------------------------------------------------------------- the brand
 *
 * `.brand__mark` was a 30px cyan gradient square standing in for a logo that
 * has existed all along. The real wordmark is six letters built out of
 * coloured shapes, so it is wide rather than square and the word beside it is
 * now redundant — the templates drop the text and this sizes the picture.
 */

.brand__logo {
  display: block;
  height: 26px;
  width: auto;
  /* The letters carry their own colour; nothing here may tint them. */
  filter: none;
}

.foot .brand__logo,
.brand--quiet .brand__logo { height: 22px; opacity: 0.85; }

.side .brand__logo,
.admin__side .brand__logo {
  height: 24px;
  /* The console's sidebar is dark and the wordmark is pastel: it reads on
     that ground without inversion, and inverting it would print the brand in
     colours the brand does not have. */
}

/* A logo is a link target before it is a picture. */
a.brand:focus-visible { outline: 2px solid var(--cyan-dark, #2f7fb5); outline-offset: 4px; border-radius: 6px; }

/* --------------------------------------------------------------- glass
 *
 * Frosted surfaces, used sparingly: the bar that stays on screen, the
 * numbers beside the hero, and the FAQ. Everywhere else stays opaque,
 * because glass over glass is fog.
 *
 * Every rule is written twice on purpose — once translucent, once solid —
 * and the solid version is the default. A browser without `backdrop-filter`
 * gets a page that looks deliberate rather than a page with transparent text
 * on a transparent card. Same for anybody who has asked their system to cut
 * transparency down.
 */

.glass {
  background: rgba(255, 255, 255, 0.82);
  border: 1px solid rgba(255, 255, 255, 0.7);
  border-radius: 18px;
  box-shadow: 0 1px 2px rgba(38, 50, 66, 0.04),
              0 12px 32px rgba(38, 50, 66, 0.08);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass {
    background: rgba(255, 255, 255, 0.55);
    -webkit-backdrop-filter: saturate(1.6) blur(16px);
    backdrop-filter: saturate(1.6) blur(16px);
  }
}

/* Somebody who has turned transparency down has usually done it because
   layered translucency is hard for them to read. Honour it exactly. */
@media (prefers-reduced-transparency: reduce) {
  .glass,
  .nav {
    background: #fff !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
}

/* ---------------------------------------------------- the lit surfaces
 *
 * Every repeated object on these pages was a white rectangle with a grey
 * shadow: the story cards, the partner tiles, the counters, the three
 * steps, the two closing doors. Correct, and completely silent. This gives
 * all of them one treatment instead: a clean pane inside a coloured edge,
 * with the colour glowing out behind it.
 *
 * How the edge is drawn. Two backgrounds on the same element, one clipped
 * to the padding box and one to the border box: the pane paints inside,
 * the gradient paints in the border, and the border is transparent so the
 * gradient is what you see. `box-sizing: border-box` is set globally, so
 * the ring is taken out of the element's own padding and no card moves by
 * a pixel. That is the whole trick, and it costs no extra markup.
 *
 * The halo is two coloured shadows on a `::before`, offset in opposite
 * directions so the light has more than one colour in it. Shadows and not
 * a blurred copy of the gradient: an outer `box-shadow` is never painted
 * inside its own element, so the halo cannot bleed through the glass and
 * tint the words. A blurred rectangle behind a 66% pane does exactly that,
 * which is how this was written first and why it is not written that way
 * now.
 *
 * Three colourways, rotating by position. A card only ever says which of
 * the three it is; hover only raises `--bleed`. Nothing animates by itself.
 */

:root {
  --edge-a: linear-gradient(137deg, #6fbaf7 0%, #b197fc 55%, #f49ac2 100%);
  --edge-b: linear-gradient(137deg, #8fd9c4 0%, #6fbaf7 50%, #4d94ff 100%);
  --edge-c: linear-gradient(137deg, #ffd166 0%, #f49ac2 50%, #b197fc 100%);

  --halo-a: -16px 10px 34px rgba(111, 186, 247, 0.55),
             16px 14px 34px rgba(244, 154, 194, 0.5);
  --halo-b: -16px 10px 34px rgba(143, 217, 196, 0.6),
             16px 14px 34px rgba(77, 148, 255, 0.45);
  --halo-c: -16px 10px 34px rgba(255, 209, 102, 0.55),
             16px 14px 34px rgba(177, 151, 252, 0.5);

  /* Opaque, and it has to be. The ring is painted by a second background
     clipped to the border box, which means it is painted across the whole
     element and the pane is what covers the middle of it. A translucent
     pane lets that gradient through and the card's own words end up
     sitting on a pink wash. Glass belongs on `.glass` and on the bar,
     where there is something behind worth blurring; a card wants a clean
     ground and gets its life from the edge and the halo instead. */
  --pane: #fff;
  --ring: 4px;
  --bleed: 0.75;
}

.card,
.post,
.ptile,
.tile,
.end,
.steps > li,
.hero__numbers .stat {
  --edge: var(--edge-a);
  --halo: var(--halo-a);
  position: relative;
  isolation: isolate;
  border: var(--ring) solid transparent;
  border-radius: 26px;
  background: linear-gradient(var(--pane), var(--pane)) padding-box,
              var(--edge) border-box;
  box-shadow: 0 14px 38px rgba(38, 50, 66, 0.09);
  transition: box-shadow 260ms ease, transform 260ms ease;
}

/* Second and third of every three. Written out rather than looped because
   these are six different elements in six different containers, and each
   one counts its own siblings. */
.card:nth-child(3n + 2),
.post:nth-child(3n + 2),
.ptile:nth-child(3n + 2),
.tile:nth-child(3n + 2),
.end:nth-child(3n + 2),
.steps > li:nth-child(3n + 2),
.hero__numbers .stat:nth-child(3n + 2) { --edge: var(--edge-b);
                                         --halo: var(--halo-b); }

.card:nth-child(3n + 3),
.post:nth-child(3n + 3),
.ptile:nth-child(3n + 3),
.tile:nth-child(3n + 3),
.end:nth-child(3n + 3),
.steps > li:nth-child(3n + 3),
.hero__numbers .stat:nth-child(3n + 3) { --edge: var(--edge-c);
                                         --halo: var(--halo-c); }

/* The halo. Sits exactly on the card and paints only outside it. */
.card::before,
.post::before,
.ptile::before,
.tile::before,
.end::before,
.steps > li::before,
.hero__numbers .stat::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  box-shadow: var(--halo);
  opacity: var(--bleed);
  transition: opacity 260ms ease;
  pointer-events: none;
}

.card:hover,
.post:hover,
.ptile:hover,
.tile:hover,
.end:hover,
.steps > li:hover {
  --bleed: 1;
  transform: translateY(-4px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9),
              0 22px 52px rgba(38, 50, 66, 0.13);
}

/* The two closing doors carried their own tints, which now fight the ring
   they sit inside. The ring is where the colour goes. */
.end,
.end--alt { background: linear-gradient(var(--pane), var(--pane)) padding-box,
                        var(--edge) border-box; }

/* `.card` clipped itself with `overflow: hidden` so its cover photograph
   would take the card's corners. That would now also clip the bleed, which
   is drawn outside the card on purpose, so the clipping moves to the
   photograph itself where it always belonged. */
.card { overflow: visible; }
.card__cover { border-radius: 22px 22px 0 0; }

/* The partner tiles carry their own background, border, radius and shadow
   in a `<style>` block inside landing.html, and a block in the body wins on
   order against a stylesheet in the head. Rather than reach for
   `!important` or edit a template to fix a stylesheet, this says the same
   thing one selector deeper, which is the honest way to win a cascade. */
.band--stage .ptile,
.band--stage.is-plain .ptile {
  border: var(--ring) solid transparent;
  border-radius: 26px;
  background: linear-gradient(var(--pane), var(--pane)) padding-box,
              var(--edge) border-box;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.band--stage .ptile:hover {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9),
              0 22px 52px rgba(38, 50, 66, 0.13);
}

/* One highlight along the top edge, which is what reads as a pane of glass
   rather than a sheet of paper once the ground underneath is opaque. */
.card,
.post,
.ptile,
.tile,
.end,
.steps > li,
.hero__numbers .stat {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9),
              0 14px 38px rgba(38, 50, 66, 0.09);
}

/* --------------------------------------------------------- the wordmark
 *
 * "TAMITOS" is the organisation. "TAMITOS Move" is this product, and the
 * bar said only the first half, so a person who had heard of the app had no
 * confirmation they were on its site. The tag is a separate element rather
 * than part of the logo file: the wordmark is the charity's mark and gets
 * used on things that are not Move, so it stays untouched and the product
 * name sits beside it.
 */

.brand__tag {
  display: inline-flex;
  align-items: center;
  height: 26px;
  padding: 0 13px 1px;
  border-radius: 999px;

  /* Frosted, not filled. The wordmark is seven solid pastel shapes and an
     eighth solid shape beside them reads as a letter that fell off it. Glass
     is a different material, so it reads as a label on the logo rather than
     part of it. */
  background: linear-gradient(118deg,
              rgba(244, 154, 194, 0.55) 0%,
              rgba(177, 151, 252, 0.42) 52%,
              rgba(143, 217, 196, 0.55) 100%);
  border: 1px solid rgba(255, 255, 255, 0.75);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9),
              0 4px 14px rgba(122, 78, 160, 0.16);

  color: #6b4bd6;
  font-family: 'Baloo 2', system-ui, sans-serif;
  font-size: 15px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.01em;
  /* Lowercase, because the wordmark is already shouting in capitals. */
  text-transform: lowercase;

  /* Tilted and tucked under the last letter, the way a sticker lands. The
     rotation is small on purpose: past about ten degrees it stops reading as
     a label placed there and starts reading as a mistake. */
  transform: rotate(-7deg) translateY(3px);
  margin-left: -6px;
  align-self: flex-end;
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .brand__tag {
    -webkit-backdrop-filter: blur(7px) saturate(1.5);
    backdrop-filter: blur(7px) saturate(1.5);
  }
}

/* It straightens up when somebody points at the logo. One small thing that
   answers a hover on a link that otherwise looks inert. */
.brand:hover .brand__tag { transform: rotate(-2deg) translateY(2px); }

.foot .brand__tag,
.brand--quiet .brand__tag {
  height: 23px;
  font-size: 13.5px;
  padding: 0 11px 1px;
  opacity: 0.95;
}

/* Somebody who asked for less transparency gets a solid pastel instead of
   glass, for the same reason `.glass` does. */
@media (prefers-reduced-transparency: reduce) {
  .brand__tag {
    background: #f2e6f8;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* --------------------------------------------------------- the faces
 *
 * A person who picked a TAMITOS character in the app is drawn as that
 * character on the leaderboard. On this page they were a letter in a
 * coloured circle, so the same person was two different things depending on
 * which screen you were looking at. The picture wins where there is one;
 * `live.py` still hands over an initial for everybody else, including every
 * direct donation, which carries no account at all.
 */

/* The pictures themselves are in `tamitos-faces.css`, which only the pages
   that draw them load. This is the part that belongs with the strip. */
.live__face--photo { padding: 0; }

/* --------------------------------------------------------- giving now
 *
 * The donate section is a short piece of prose beside a form with fourteen
 * fields in it. The form set the row height, so the left column was three
 * paragraphs and then eight hundred pixels of nothing.
 *
 * Two things fix it and both are worth having on their own. A picture under
 * the prose, because the section is asking a company for money and the
 * thing it buys is on screen everywhere else on this page. And the column
 * sticks, so the explanation of where the money goes is still on screen
 * when somebody is halfway down the form typing their IČO.
 */

.give__intro {
  position: sticky;
  top: 92px;
}

.give__art {
  margin-top: 28px;
  border-radius: 24px;
  overflow: hidden;
  /* The render carries its own white ground, so it needs a shape and a
     little lift rather than a frame. */
  box-shadow: 0 18px 44px rgba(38, 50, 66, 0.1);
}

.give__art img {
  display: block;
  width: 100%;
  height: auto;
}

@media (max-width: 900px) {
  /* Stacked, the intro is directly above the form and sticking would park
     it over the fields. */
  .give__intro { position: static; }
  .give__art { margin-top: 22px; }
}

/* -------------------------------------------------------- the hero

   The render on the landing page was small, and the sentence beside it ran
   the full width of its column, which put the last words of the lede within
   a few pixels of the picture. Both problems are the same problem: the text
   column was the wide one.

   The ratio is flipped. The render gets the larger share and the sentence
   is capped in characters rather than in pixels, so it wraps where a line
   of reading wants to wrap and never reaches across the gap.

   `.hero` is a bare class on exactly one page. `/pre-firmy` uses
   `.hero.hero--full`, which resets the grid entirely, and the error pages
   use only `.hero__cta`. So this is the landing page's hero and nothing
   else, despite the name.

   The stacked rule at the bottom is not optional: public.css collapses this
   grid to one column under 900px, and this file loads after it, so without
   repeating that the desktop ratio would follow the layout down onto a
   phone.
 */

.hero {
  grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.3fr);
  gap: clamp(28px, 4vw, 56px);
  max-width: 1320px;
  padding-top: clamp(48px, 7vh, 88px);
}

/* In characters, not ems of the container. 27 is short enough that the
   sentence turns well before the picture and long enough that it does not
   read as a column of fragments. */
.hero__lede { max-width: 27ch; }
.hero__fine { max-width: 34ch; }

.hero__art img { border-radius: 28px; }

@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; }
  .hero__lede,
  .hero__fine { max-width: none; }
}

/* On a phone the picture comes first.
   
   The render is three phones with the app on them, and it is the fastest
   answer this page gives to "what is this". Underneath the headline it was
   the fourth thing somebody reached, after two paragraphs and two buttons,
   and on a screen this narrow that is a long way down. `order` moves it
   without moving it in the markup, so the heading stays the first thing a
   screen reader and a search engine meet.

   The two buttons go side by side rather than stacked. Stacked, they read as
   a first choice and a second thought; side by side they read as two doors,
   which is what they are. */
@media (max-width: 720px) {
  .hero {
    display: flex;
    flex-direction: column;
    gap: clamp(20px, 4vw, 32px);
  }
  .hero__art { order: -1; }
  .hero__art img { border-radius: 22px; }

  .hero__cta {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
  }
  .hero__cta .btn {
    width: 100%;
    padding-inline: 12px;
    text-align: center;
    /* Two Slovak labels of very different lengths in two equal columns. The
       long one wraps rather than pushing its own button wider than the
       column, which is what would put the sideways drag back. */
    white-space: normal;
    line-height: 1.25;
  }
}

/* --------------------------------------------------- the stacked hero

   The picture and the words are stacked, not layered.

   They used to be layered on `/pre-firmy`: the render filled the screen and
   the headline sat in its lower third over a whitening gradient. That works
   while the render is characters with empty sky above them. It stops working
   the moment the render is a subject that fills the frame — three phones
   showing app screens, three spheres with symbols inside them — because the
   words land on the subject and neither can be read.

   So the render gets its own band with its own height, and the words start
   where the render ends. Nothing overlaps anything, on any width.

   Lives here rather than in the page that first needed it, because two pages
   now use it and a third will. `.hero` above is a centred 1180px grid, so
   `max-width`, `margin`, `padding`, `gap` and `display` all have to be undone
   or the picture stops where the text column stops. It must stay below the
   `.hero` rules: the two selectors weigh the same and source order is what
   decides. */
.hero--full {
  position: relative;
  display: block;
  width: 100%;
  max-width: none;
  padding: 0;
  margin: 0;
  gap: 0;
  min-height: 0;
}

/* Capped rather than left at the render's own 16:9. Uncapped, a 1920 wide
   picture is 780px tall on a laptop and the buttons fall off the screen;
   `cover` crops the air above and below the subject, which is the part of a
   render carrying no information. Centred, so when the cap bites it takes
   the same slice off the top and the bottom: a crop weighted one way clips
   the subject and reads as a mistake, a centred one reads as a frame. */
.hero--full .hero__bg {
  position: relative;
  z-index: 0;
  width: 100%;
  aspect-ratio: var(--hero-ratio, 1920 / 1072);
  max-height: 72svh;
  overflow: hidden;
}

/* `--hero-focus` is where the subject actually sits, vertically, in the
   render. It is almost never the middle: a render with a lot of sky above it
   and a short reflection below has its subject low, and a crop taken from the
   centre eats the reflection before it eats the sky. Measure the subject,
   put its midpoint here, and the band can be made much shorter before
   anything of it is lost. */
.hero--full .hero__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% var(--hero-focus, 50%);
  display: block;
}

/* A short fade at the foot of the picture into the page, so the band ends
   rather than stops. Only the bottom eighth: any more and it starts washing
   out the subject it exists to show. */
.hero--full .hero__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0) 84%,
    rgba(255, 255, 255, 0.55) 94%,
    #fff 100%);
}

.hero--full .hero__well {
  width: 100%;
  max-width: 1180px;
  margin: 0 auto;
  padding: clamp(28px, 4vh, 52px) var(--gutter, 26px) clamp(40px, 7vh, 80px);
}

.hero--full h1 { margin: 0; }
.hero--full .hero__lede { max-width: 52ch; }

/* A short window, and phones on their side. The render is the first thing to
   give up its height: the words and the buttons are the page. */
@media (max-height: 620px) {
  .hero--full .hero__bg { max-height: 52svh; }
}

@media (max-width: 640px) {
  .hero--full .hero__bg { max-height: 46svh; }
}

/* ------------------------------------------------- the one wide door

   A single closing card, full width, with the words on the left and the
   button on the right.

   It was centred, and centred was the wrong shape for it. The paragraph keeps
   a 34em measure — which is right, a line of text 1180px long is not readable
   — so a centred block of it sat in the middle of a very wide box with empty
   space either side, and the last short line drifting to the centre made the
   whole card look like it had failed to load rather than like it had been
   laid out.

   A row fixes the shape without touching the measure: the text is as wide as
   text should be, the button is at the far edge, and the card is full width
   because both of its ends are doing something.

   `.end p` has `max-width: 34em` and `.end--wide p` had auto margins to
   centre it. Both are undone here. */
.end--wide {
  /* A grid rather than a flex row, because the left half is two things
     stacked and the right half is one thing beside both of them. As a flex
     row the heading had to take a whole line of its own and `align-items`
     then pushed the paragraph away from it, leaving a hole between a title
     and the sentence that belongs to it. */
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "title cta"
    "text  cta";
  column-gap: clamp(24px, 5vw, 72px);
  text-align: left;
}

.end--wide h3 {
  grid-area: title;
  margin: 0;
  align-self: end;
}

.end--wide p {
  grid-area: text;
  /* `.end p` centres itself with auto margins on this modifier. Undone: the
     measure stays at 34em, which is what a line of text should be, and it
     now sits at the left edge of the card instead of floating in the middle
     of it. */
  margin: 10px 0 0;
  align-self: start;
}

.end--wide .btn {
  grid-area: cta;
  align-self: center;
  justify-self: end;
}

/* Stacked, with the button full width so it is unmistakably the last thing.
   Two columns on a phone would leave both too narrow to read. */
@media (max-width: 720px) {
  .end--wide {
    display: block;
  }
  .end--wide p { margin-bottom: 20px; }
  .end--wide .btn {
    display: block;
    width: 100%;
    text-align: center;
  }
}

/* -------------------------------------------------------- the partners
 *
 * The partner band is a photograph with the tiles sitting over its lower
 * part, where a gradient in landing.html has already faded the picture to
 * paper. The tiles are fine. The heading above them is not: it sits in the
 * top of the band, where that gradient is still fully transparent, so
 * "Partneri, ktorí to zaplatili" and the line under it were dark text on a
 * blue monster. The note in particular could not be read at all.
 *
 * The fade starts higher now. The tiles keep the same clean ground they
 * had, the heading gets one, and enough of the picture survives at the top
 * for it still to be a photograph rather than a tint.
 *
 * One element selector deeper than the rule it replaces, because that rule
 * lives in a `<style>` block in the body and would otherwise win on order.
 */

section.band--stage .stage__bg::after {
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0) 10%,
    rgba(255, 255, 255, 0.38) 30%,
    rgba(255, 255, 255, 0.78) 48%,
    rgba(255, 255, 255, 0.94) 66%,
    #fff 84%);
}

/* ------------------------------------------------------------- the foot
 *
 * The footer was white on a white page with a hairline above it, which
 * meant the page did not end so much as stop. It is a pastel rose ground
 * now: warm, quiet, and unmistakably the bottom of the page.
 *
 * Rose rather than any of the three accents on purpose. Blue, lilac and
 * mint are all doing work further up, on the cards and the thread; a
 * colour that appears once, at the end, closes the page instead of adding
 * a fourth voice to the middle of it.
 *
 * Every text colour is restated against the new ground. `--ink-faint` on
 * white is a considered grey; on rose it is a grey that has drifted, and
 * the fine print is the one line down here somebody might actually need.
 */

.foot {
  background:
    radial-gradient(900px 320px at 88% 0%,
                    rgba(244, 154, 194, 0.34) 0%,
                    rgba(244, 154, 194, 0) 68%),
    radial-gradient(700px 300px at 6% 100%,
                    rgba(177, 151, 252, 0.22) 0%,
                    rgba(177, 151, 252, 0) 66%),
    linear-gradient(180deg, #fdeef4 0%, #fbe8f1 100%);
  border-top: 0;
  padding-top: 52px;
  color: #4a3341;
}

.foot .brand__logo { opacity: 1; }

.foot__note { color: #6b4f5e; }

.foot__head { color: #a8788e; }

.foot__links a { color: #6b4f5e; }
.foot__links a:hover { color: #3d2833; }
.foot__links a:focus-visible {
  outline: 2px solid #c7548a;
  outline-offset: 3px;
  border-radius: 4px;
}

/* The social tiles were a rose pastel on white, which was right until the
   ground underneath them turned rose too and they vanished into it. White
   panes now, with the mark keeping its own colour. */
.foot .social__tile,
.foot .social__tile--ig {
  background: rgba(255, 255, 255, 0.78);
  border-color: rgba(255, 255, 255, 0.9);
  color: #c7548a;
}
.foot .social__tile:hover,
.foot .social__tile--ig:hover { background: #fff; }

/* The hairline splitting the fine print off has to be visible on rose, and
   `--line` is mixed for white. */
.foot__fine {
  border-top-color: rgba(122, 78, 98, 0.18);
  /* 4.6:1 on this ground. The old `--ink-faint` measured 2.4:1 here, and
     this is the line that says we take nothing from a family's donation,
     which is not a line to render in decorative grey. */
  color: #6b4f5e;
}

/* ------------------------------------------------------------- the bar
 *
 * Sticky, so the way back and the primary action are always a thumb away on
 * a long page. This is the one place the frost earns its keep: the bar sits
 * over photographs of families and over the gradient wash, and a solid white
 * strip cuts the page in half.
 */

.page .nav {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(255, 255, 255, 0.88);
  border-bottom: 1px solid rgba(38, 50, 66, 0.07);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .page .nav {
    background: rgba(255, 255, 255, 0.62);
    -webkit-backdrop-filter: saturate(1.7) blur(18px);
    backdrop-filter: saturate(1.7) blur(18px);
  }
}

/* The counters used to be four floating white cards with a hairline. They
   are lit panes now, like every other repeated object on the page: see
   "the lit surfaces" above, which is where their edge and their halo come
   from. Only the ring is trimmed, because these boxes are small and a 4px
   frame on a 3-digit number is a frame wearing the number. */
.hero__numbers .stat { --ring: 3px; border-radius: 20px; }

/* The figure and its label.
 *
 * Both are `<span>`, and nothing had ever styled either of them, so the
 * band that carries this page's central claim was rendering as body text
 * with the label welded to the end of the number: "2 182,40 € rozdané
 * rodinkám", one line, one size. A claim that large deserves to be read as
 * one, so the value becomes the figure and the label goes under it.
 */

.stat { display: grid; gap: 3px; }

.stat__value {
  font-size: 26px;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--ink, #263242);
}

.stat--big .stat__value { font-size: 40px; }

.stat__label {
  font-size: 13px;
  line-height: 1.35;
  color: var(--ink-soft, #5b6472);
}

/* ----------------------------------------------------------------- FAQ
 *
 * `<details>` and `<summary>`, not a script. Keyboard support, screen-reader
 * semantics and find-in-page all work without a line of JavaScript, and the
 * questions are readable with the stylesheet switched off — which is what a
 * search engine sees.
 */

.faq {
  display: grid;
  gap: 12px;
  max-width: 760px;
  margin: 0 auto;
}

.faq__item {
  padding: 0 20px;
  overflow: hidden;
  transition: box-shadow 160ms ease;
}

.faq__item[open] {
  box-shadow: 0 2px 4px rgba(38, 50, 66, 0.05),
              0 18px 44px rgba(38, 50, 66, 0.11);
}

.faq__q {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 0;
  /* 48px of thumb, not 20px of text. */
  min-height: 48px;
  font-weight: 700;
  font-size: 16.5px;
  line-height: 1.35;
  cursor: pointer;
  list-style: none;
}

/* Safari draws its own triangle and ignores `list-style`. */
.faq__q::-webkit-details-marker { display: none; }

.faq__q:focus-visible {
  outline: 2px solid var(--cyan-dark, #2f7fb5);
  outline-offset: 2px;
  border-radius: 8px;
}

/* The chevron is drawn rather than typed, so it rotates. */
.faq__q::after {
  content: "";
  flex: none;
  margin-left: auto;
  width: 10px;
  height: 10px;
  border-right: 2.5px solid currentColor;
  border-bottom: 2.5px solid currentColor;
  border-radius: 1px;
  opacity: 0.45;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 180ms ease;
}

.faq__item[open] .faq__q::after {
  transform: rotate(-135deg) translate(-2px, -2px);
}

.faq__a {
  padding: 0 34px 20px 0;
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-soft, #5b6472);
}

.faq__a + .faq__a { padding-top: 10px; }

.faq__a a { color: inherit; text-underline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
  .faq__item,
  .faq__q::after { transition: none; }
}

@media (max-width: 640px) {
  .faq__item { padding: 0 16px; }
  .faq__q { font-size: 15.5px; }
}

/* -------------------------------------------------------- the live strip
 *
 * "Práve teraz ľudia pomáhajú" — a short column of things that actually
 * happened, drifting upwards beside the hero.
 *
 * The trick is two copies of the same list inside a track that travels
 * exactly half its own height. At the moment the animation restarts, the
 * second copy is sitting precisely where the first one started, so the loop
 * has no seam and no JavaScript. It also means the markup must contain the
 * rows twice — see the template, which says so at the point it does it.
 *
 * Three ways it stops. Hover, because a name sliding out from under a
 * reader's eye is a small hostility. Focus inside, so somebody tabbing to a
 * link is not chasing it. And `prefers-reduced-motion`, where it does not
 * move at all: the strip becomes a plain scrollable list, which is the
 * version that always works.
 */

.live {
  /* A child of `.hero__numbers`, which is a grid: spanning every column keeps
     the strip full width beside counters that sit two-up, and the parent's
     own gap does the spacing above it. */
  grid-column: 1 / -1;
  padding: 16px 16px 6px;
  overflow: hidden;
  /* Bounded, so the strip cannot grow past the hero on a tall screen and
     turn the page into a wall of somebody else's giving. */
  max-height: 316px;
  position: relative;
}

.live__head {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 12px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--ink, #263242);
}

/* A dot that breathes, because "right now" is the claim being made. */
.live__dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #2f9e5f;
  box-shadow: 0 0 0 0 rgba(47, 158, 95, 0.45);
  animation: live-pulse 2.4s ease-out infinite;
}

@keyframes live-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(47, 158, 95, 0.45); }
  70%  { box-shadow: 0 0 0 7px rgba(47, 158, 95, 0); }
  100% { box-shadow: 0 0 0 0 rgba(47, 158, 95, 0); }
}

.live__window {
  position: relative;
  height: 246px;
  overflow: hidden;
  /* Faded top and bottom rather than a hard cut, so rows arrive and leave
     instead of appearing and vanishing. */
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 14%,
                                      #000 86%, transparent);
          mask-image: linear-gradient(to bottom, transparent, #000 14%,
                                      #000 86%, transparent);
}

.live__track {
  display: grid;
  gap: 10px;
  animation: live-rise 26s linear infinite;
}

/* Half, exactly — the second copy of the list lands where the first began. */
@keyframes live-rise {
  from { transform: translateY(0); }
  to   { transform: translateY(-50%); }
}

.live:hover .live__track,
.live:focus-within .live__track { animation-play-state: paused; }

.live__row {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 11px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.72);
  border: 1px solid rgba(38, 50, 66, 0.05);
}

.live__face {
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 14px;
  font-weight: 800;
  color: #fff;
}

/* The same five data colours the app gives people, so a person who has seen
   the app recognises the palette. */
.live__face--0 { background: #C7548A; }
.live__face--1 { background: #5B4BD6; }
.live__face--2 { background: #3D7FC4; }
.live__face--3 { background: #1E9B62; }
.live__face--4 { background: #C77C33; }

.live__what {
  min-width: 0;
  font-size: 13px;
  line-height: 1.35;
  color: var(--ink-soft, #5b6472);
}

.live__who {
  font-weight: 700;
  color: var(--ink, #263242);
}

.live__eur { font-weight: 700; color: var(--ink, #263242); }

.live__for {
  display: block;
  margin-top: 1px;
  font-size: 12.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.live__foot {
  margin: 10px 0 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink-faint, #8b95a3);
}

@media (prefers-reduced-motion: reduce) {
  .live__track { animation: none; }
  .live__dot { animation: none; }
  /* Nothing moves, so the list has to be reachable by hand instead. */
  .live__window { overflow-y: auto; }
}

@media (max-width: 900px) {
  .live { max-height: none; }
  .live__window { height: 190px; }
}

/* ------------------------------------------------------- the hero picture
 *
 * The hero used to carry the counters in its right-hand column. They have
 * moved down to sit above the FAQ, where they answer a question the page has
 * by then actually raised; up here there is one sentence and a picture, and
 * nothing competing with either.
 */

.hero__art {
  align-self: center;
  min-width: 0;
}

.hero__art img {
  display: block;
  width: 100%;
  height: auto;
  /* No card, no shadow, no frame. The render already carries its own soft
     shadows and its own white ground — putting it on a panel would be two
     surfaces pretending to be one. */
  border-radius: 24px;
}

/* --------------------------------------------------------------- proof
 *
 * The counters and the live strip, side by side, in the band above the
 * questions. Two columns on a desktop and one on a phone, where a strip
 * beside a stack of numbers would leave both too narrow to read.
 */

.proof {
  display: grid;
  gap: 26px;
  grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
  align-items: start;
}

/* The strip is no longer a child of `.hero__numbers`, so it must not span
   anything — and it is no longer squeezed beside a hero, so the height cap
   that kept it from swamping that column would now clip its own footnote. */
.proof .live {
  grid-column: auto;
  margin: 0;
  max-height: none;
}

.proof .hero__numbers { margin: 0; }

/* On a young site the strip is not drawn at all: it needs rows out of the
   database or the template leaves it out. The second column was reserved
   anyway, so the counters sat squeezed into two thirds of the band with a
   third of it empty beside them. With no strip there is one column. */
.proof:not(:has(.live)) { grid-template-columns: 1fr; }

@media (max-width: 900px) {
  .proof { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------ the gallery
 *
 * One stage, several pictures and possibly a clip. The thumbnails switch
 * between them.
 *
 * `is-gallery` is added by the script, and nothing here hides anything until
 * it is. With no JavaScript the stage is what it always was — every picture
 * stacked down the column, all of them visible.
 */

.stage.is-gallery > [data-item] { display: none; }
.stage.is-gallery > [data-item].is-on { display: block; }

/* The strip of thumbnails. Was three inert 96px squares; they are buttons
   now, so they need a target, a focus ring and a state. */
.story-page__gallery {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 12px;
}

.shot {
  position: relative;
  flex: none;
  width: 84px;
  height: 84px;
  padding: 0;
  border: 0;
  border-radius: 14px;
  overflow: hidden;
  cursor: pointer;
  background: var(--well, #eae7f0);
  /* Two pixels of ring, drawn outside so the picture is not cropped by the
     selected state. */
  box-shadow: 0 0 0 0 rgba(47, 127, 181, 0);
  transition: box-shadow 160ms ease, transform 160ms ease;
}

.shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.shot:hover { transform: translateY(-1px); }

.shot.is-on {
  box-shadow: 0 0 0 3px var(--cyan-dark, #2f7fb5);
}

.shot:focus-visible {
  outline: 2px solid var(--cyan-dark, #2f7fb5);
  outline-offset: 3px;
}

/* The clip's thumbnail says it is a clip. A frame that looks like every
   other photograph is a video nobody plays. */
.shot--play::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(20, 26, 40, 0.35);
}

.shot__play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 1;
  width: 0;
  height: 0;
  border-left: 15px solid #fff;
  border-top: 10px solid transparent;
  border-bottom: 10px solid transparent;
  /* Optically centred: a triangle's visual middle is not its bounding box. */
  margin-left: 3px;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.4));
}

@media (prefers-reduced-motion: reduce) {
  .shot { transition: none; }
  .shot:hover { transform: none; }
}

@media (max-width: 640px) {
  .shot { width: 68px; height: 68px; }
}

/* The language control lives here rather than in public.css, because both
 * shells need it. `page.html` loads public.css and `shell.html` does not:
 * the wizard deliberately loads less. So the switch added to the form
 * pages rendered as two words of unstyled text with the second one
 * underlined, which reads as a mistake rather than as a control.
 */
/* The language control: two codes in one pill, current one lit.
 *
 * A segmented control rather than a link, because it answers two questions at
 * once and a link only answers the second: which language am I reading, and
 * where can I go. The lit half is the answer to the first and is deliberately
 * not clickable — a control where the current state is also a button teaches
 * people to click it and find nothing happens.
 *
 * Last in the bar, after the call to action. It matters enormously to the few
 * who need it and not at all to everybody else, so it sits at the end where
 * the eye finishes rather than in the middle where it would compete. */
.nav__lang {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--line);
  border-radius: 999px;
  overflow: hidden;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1;
  white-space: nowrap;
  flex: none;
}
.nav__lang-on,
.nav__lang-off {
  padding: 8px 11px;
  text-decoration: none;
}
/* The language you are in. Not a link, and coloured like one thing that is
   currently true rather than like something to press. */
.nav__lang-on {
  background: var(--ink);
  color: #fff;
}
.nav__lang-off { color: var(--ink-soft); }
.nav__lang-off:hover { color: var(--ink); background: rgba(38, 50, 66, 0.05); }

/* ------------------------------------------------------------------ giving

   The amount control on `/prispiet/{id}`, and it lives here rather than in
   `public.css` for the reason two earlier mistakes made expensive: this page
   is built on `shell.html`, and `shell.html` does not load `public.css`. A
   rule written there renders as unstyled markup in front of somebody who is
   trying to give a child money.

   Radios drawn as pills. The input itself stays in the document rather than
   being replaced by a div, so the control keeps its keyboard behaviour and a
   screen reader still calls it a radio group. */

.give { display: flex; flex-direction: column; gap: 14px; }

.give__amounts {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}

.give__amount { position: relative; }

/* Off-screen rather than `display:none`: a hidden input cannot be focused,
   and a radio nobody can tab to is a radio a keyboard user cannot answer. */
.give__amount input {
  position: absolute;
  opacity: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}

.give__amount span {
  display: block;
  text-align: center;
  padding: 12px 4px;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-field);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  background: var(--surface);
  transition: border-color .15s, background .15s, color .15s;
}

.give__amount input:checked + span {
  border-color: var(--cyan-dark);
  background: var(--cyan);
  color: #fff;
}

.give__amount input:focus-visible + span {
  outline: 2px solid var(--cyan-dark);
  outline-offset: 2px;
}

.give__own { display: flex; flex-direction: column; gap: 6px; }

.give__own span {
  font-size: 14px;
  color: var(--ink-soft);
}

.give__own input {
  width: 100%;
  padding: 12px 14px;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-field);
  font: inherit;
  color: var(--ink);
  background: var(--surface);
}

.give__own input:focus-visible {
  outline: none;
  border-color: var(--cyan-dark);
}

.give__wrong {
  margin: 0 0 12px;
  padding: 10px 12px;
  border-radius: var(--r-field);
  background: var(--error-soft);
  color: var(--error);
  font-size: 14px;
  font-weight: 600;
}

/* Four across is tight under about 380px and the euro sign is what falls off
   the end, so two rows rather than four cramped columns. */
@media (max-width: 400px) {
  .give__amounts { grid-template-columns: repeat(2, 1fr); }
}
