/* Tierheimfinder — Steckbrief, part two: what lies in the lists.
 *
 * Part one is `design-steckbrief.css`: the fonts, the two palettes, the reset,
 * the masthead, the filter row, the buttons and the front door. This file is
 * the animal card, the skeletons, the shelter list, one shelter's own page,
 * konto and Merkliste, the footer, the widths — and at its very foot the two
 * phone layouts.
 *
 * The two files are one look and are linked in this order: `gestaltung.py`
 * names them as a list and the template writes one <link> per entry. The order
 * is not a convenience — the media blocks near the end of this file override
 * rules that stand higher up in it, and a swapped link would turn that around.
 *
 * Nothing here leans on any other look, exactly as before. The split was made
 * on 2026-08-04 (OP191): the one file had passed the two-thousand-line ceiling
 * of house rule 25, and `tests/test_frontend_split.py` measures every
 * stylesheet since the same commit.
 */

/* ============================================================== the dossier */
/* Fewer, larger, better: at 360 a card is the full 328 pixels of the content
   width, and the photograph on it is 328 by 410. */
.tier-gitter {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    column-gap: var(--s5);
    row-gap: var(--s6);
}

/* The card is a grid and not a stack, and that is what lets the flat run of
   elements the JavaScript emits become a headed block with a data list under
   it — see `.tier-zeile` below. Rows the record has nothing for collapse to
   nothing, because the grid has no row gap: the spacing is each row's own
   padding. */
.tier {
    /* 1420 of these on one page. Two lines, and the largest rendering gain
       there is. The guess is a card with a 4:5 photograph and four rows. */
    content-visibility: auto;
    contain-intrinsic-size: auto 620px;
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: 0;
    padding-bottom: var(--s4);
    background: var(--bg-bar);
    border: 1px solid var(--line);
    /* Square, and no `overflow: hidden` with it. Both are the same decision:
       the photograph runs to the card's own edge, and a rounded card would
       have to clip it — which would also clip the focus ring of the
       photograph's link, the largest target on the card. A printed dossier has
       square corners anyway. */
    border-radius: 0;
}
/* The whole motion budget of this look: two pixels, and the frame darkens. */
.tier:hover { transform: translateY(-2px); border-color: var(--line-strong); }

.tier-haupt {
    grid-area: 1 / 1 / 2 / 3;
    display: block;
    text-decoration: none;
    color: inherit;
    /* Only so the found-animal band and the heart can stand on the
       photograph. */
    position: relative;
    margin-bottom: var(--s4);
}

/* Standing, not square: 4:5 is the portrait an animal is photographed in, and
   it is the single strongest difference between this look and a grid of
   thumbnails. */
.tier-foto {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 5;
    object-fit: cover;
    /* A shelter photograph is a full-body shot with the head in the upper
       half, and a centred crop takes the head off a standing dog. */
    object-position: 50% 35%;
    background: var(--bg-sunk);
    /* Not a shadow: a containment line drawn inside the picture, so it costs
       no layout and stops a pale photograph bleeding into the card. */
    box-shadow: inset 0 0 0 1px var(--photo-edge);
}

/* The 1.6% of animals with no photograph at all, and — while a picture is on
   its way — every other one. Type doing an icon's job: the initial letter in
   the serif, not a grey silhouette on a grey field. */
.tier-leer {
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--schrift-titel);
    font-size: 3rem;
    font-weight: 300;
    font-variation-settings: 'opsz' 48;
    color: var(--ink-2);
}
/* A letter that is a stand-in and not text: it is gone a second later, and a
   selection dragged across the page must not copy one out of every card whose
   picture had not landed yet. */
.tier-foto-wartet { user-select: none; }

/* The two containers the grid steps over. Their children — the name, the share
   control, the breed and the waiting mark — are the cells of the card, and a
   box around any of them would stop them lining up with the rows below. Both
   are plain containers with nothing else on them, so nothing is lost by it. */
.tier-zeile { display: contents; }
.tier-rasse { display: contents; }

.tier-name {
    grid-area: 2 / 1;
    min-width: 0;
    padding: 0 0 0 var(--s4);
    font-family: var(--schrift-titel);
    font-size: var(--t-xl);
    font-weight: 500;
    font-variation-settings: 'opsz' 24;
    line-height: 1.15;
    letter-spacing: -0.005em;
    color: var(--ink);
    /* One line with dots. Two cards side by side have to keep their data lists
       at the same height, and a name that wrapped pushed one card's rows a
       line lower than its neighbour's. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-decoration: none;
}
a.tier-name:hover { text-decoration: underline; }

/* The breed, or the species where no breed is known — and the one place this
   look uses Fraunces' second file. */
.tier-rasse-wort {
    grid-area: 4 / 1 / 5 / 3;
    padding: var(--s1) var(--s4) var(--s4);
    font-family: var(--schrift-titel);
    font-style: italic;
    font-size: var(--t-md);
    font-weight: 400;
    font-variation-settings: 'opsz' 17;
    line-height: 1.3;
    color: var(--ink-2);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --------------------------------------------------------- the data list */
.tier-alter,
.tier-fuss,
.tier-zeit,
.tier-stoerung {
    grid-column: 1 / -1;
    padding: var(--s2) var(--s4);
    border-top: 1px solid var(--line);
    font-size: var(--t-sm);
    line-height: 1.5;
    color: var(--ink);
    min-width: 0;
    overflow-wrap: break-word;
}
/* The two rows that carry a label. The padding holds the value's column and
   the negative indent pulls the label back out into it, so a value too long
   for one line wraps under itself and never under the label. */
.tier-alter,
.tier-fuss {
    padding-left: calc(var(--s4) + var(--daten-spalte));
    text-indent: calc(-1 * var(--daten-spalte));
}
/* The card is a hand-placed grid, so a new child with no row of its own would
   auto-place on top of a line that is already there. The trouble line goes
   directly under the shelter's own row, which is where it belongs, and the
   listing age moves down one: 5 Alter, 6 Marke, 7 Tierheim, 8 Störung, 9 Zeit,
   10 the list menu (further down this file, and unchanged). */
.tier-alter    { grid-row: 5; }
.tier-fuss     { grid-row: 7; }
.tier-stoerung { grid-row: 8; }
.tier-zeit     { grid-row: 9; }

/* Amber and heavier than the rows above it: this is the one line on the card
   that says the facts above may be out of date. It takes no label column —
   it is a sentence and not a reading. */
.tier-stoerung {
    font-size: var(--t-xs);
    color: var(--warn);
    font-weight: 600;
}

.tier-alter::before,
.tier-fuss::before {
    display: inline-block;
    width: var(--daten-spalte);
    text-indent: 0;
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-2);
}
.tier-alter::before { content: "Alter"; }
.tier-fuss::before  { content: "Tierheim"; }

.tier-heim { color: var(--brand); text-decoration: none; }
.tier-heim:hover { text-decoration: underline; }
.tier-ort { color: var(--ink-2); }

/* Langzeitgäste only, and it reads as a sentence already — "gelistet seit
   12. März 2024" — so it takes no label and no label column. */
.tier-zeit {
    color: var(--ink-2);
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------- die Wartezeile */
/* The one thing the site knows that no shelter website shows: how long this
   animal has been waiting. It is a line of words and nothing else — the date
   on the left, straight out of the marker's own title, which app.js writes no
   finer than the shelter published it, and the duration in the site's own
   words on the right ("87 Tage", "über 1 Jahr").
 *
 * There was a three-pixel bar under it until 2026-08-08, a year wide, filled
 * to the middle of whichever of the four `data-wartet` buckets the animal was
 * in. Georg had it taken out: the line already says the number, and the bar
 * could only ever say it more vaguely. `data-wartet` stays on the tile — the
 * other looks read it, and the long waiters are still marked here in the
 * words' own colour, two rules below. */
.tier-marke {
    grid-area: 6 / 1 / 7 / 3;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s3);
    padding: var(--s2) var(--s4);
    border-top: 1px solid var(--line);
    font-size: var(--t-sm);
    color: var(--ink-2);
    font-variant-numeric: tabular-nums;
}
.tier-marke::before {
    content: attr(title);
    /* "Mindestens seit März 2024" is the longest this ever gets, and on a
       three-column screen the card is under 300 pixels wide. The caption is
       the half that gives way; the duration on the right never does. */
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-2);
}
.tier-marke { flex-wrap: nowrap; }
/* A marker with no caption at all: its count starts at this site's own first
   sighting, so there is no published date to name. The empty ::before would
   still hold its place, so it is taken out — but the duration stays in the
   right-hand column with every other card's, which is where the eye reads a
   number (Georg, 2026-08-06). It was flush left from 2026-08-04, on the
   reading that a lone number at the far right looked like a column of its
   own; a row of cards where one number sits under the others is worse. */
.tier-marke:not([title])::before { display: none; }
.tier-marke:not([title]) { justify-content: flex-end; }

/* Nothing is drawn after the card. The rule stands so that a later hand
   cannot put a mark back into the corner without reading the paragraph at the
   top of this section. */
.tier::after { content: none; }
/* Over a year, and now said in the words alone: scrolling the page you can
   still see the long waiters without reading them, because the line is amber
   and heavier than its neighbours. */
.tier[data-wartet="lang"] .tier-marke { color: var(--lang); font-weight: 600; }
.tier[data-wartet="lang"] .tier-marke::before { color: var(--lang); }

/* -------------------------------------- Fundtiere, Vermittlungsfälle */
/* Two marks on one card, on purpose. This one is for the eye going past at
   speed, and no photograph can wash it out because the fill is opaque. It is
   aria-hidden, so a screen reader gets the sentence under the name once and
   not twice. Bottom left, because the heart owns the top right. */
.tier-fund-band,
.tier-vermittlung-band {
    position: absolute;
    left: var(--s3);
    bottom: var(--s3);
    padding: 3px var(--s2);
    font-family: var(--schrift-text);
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    background: var(--fund);
    color: var(--on-fund);
    border-radius: var(--r-photo);
    pointer-events: none;
}

/* And this one is for the eye that has stopped: the band says what the animal
   is, this says what it means for the person reading. Above the breed, because
   it changes what the whole card is about, and a filled box rather than a
   coloured line — it must not be read past. */
.tier-fund-hinweis,
.tier-vermittlung-hinweis {
    grid-area: 3 / 1 / 4 / 3;
    margin: var(--s2) var(--s4) 0;
    padding: var(--s2) var(--s3);
    font-size: var(--t-sm);
    line-height: 1.4;
    font-weight: 500;
    background: var(--fund);
    color: var(--on-fund);
    border-radius: var(--r-photo);
    overflow-wrap: break-word;
}

/* All that separates the two marks, and deliberately all: the amber says "do
   not fall for this one", while a Vermittlungsfall is an animal somebody really
   can take home — it simply does not sleep at the address under it. This look's
   own accent says "read me" without saying "beware". Last, so it wins over the
   fill above. */
.tier-vermittlung-band,
.tier-vermittlung-hinweis {
    background: var(--brand);
    color: var(--on-brand);
}

/* ----------------------------------------------------------------- the heart */
/* On the photograph's top-right corner and outside the photograph's own link —
   a button inside an anchor is invalid markup and does not click. No plate
   behind it: the outline stands on the picture itself, white with a shadow on
   the strokes, which reads on a pale photograph and a dark one alike. At 360
   its word lives in the aria-label. */
.tier-merken {
    position: absolute;
    top: var(--s2);
    right: var(--s2);
    z-index: 2;
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    background: transparent;
    border-radius: var(--r-control);
    color: var(--foto-ink);
    filter: drop-shadow(0 1px 3px var(--foto-schatten));
    cursor: pointer;
}
.tier-merken svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; }
.tier-merken:hover { transform: scale(1.1); }
/* On keeps the white outline around the filled plum: the light theme's plum is
   nearly black, and a filled dark heart alone would sink into a dark
   photograph — the very failure a plate used to prevent. */
.tier-merken.gemerkt { color: var(--brand); }
.tier-merken.gemerkt svg { fill: currentColor; stroke: var(--foto-ink); }
/* While the press is in the air. Never the opacity property, which reads as
   disabled rather than as busy. */
.tier-merken.wartet { color: var(--foto-ink-leise); }
/* A card with no photograph at all: the heart stands on the sunk tone there,
   where white ink and a shadow are the wrong tools. Keyed on the permanent
   letter only — a card whose picture is merely pending must keep the
   photograph's colours from the first paint, or every heart on the first
   screenful would flip the moment its picture lands. */
.tier:has(.tier-leer:not(.tier-foto-wartet)) .tier-merken { color: var(--ink); filter: none; }
.tier:has(.tier-leer:not(.tier-foto-wartet)) .tier-merken.gemerkt { color: var(--brand); }
.tier:has(.tier-leer:not(.tier-foto-wartet)) .tier-merken.gemerkt svg { stroke: currentColor; }
.tier:has(.tier-leer:not(.tier-foto-wartet)) .tier-merken.wartet { color: var(--ink-2); }

/* ------------------------------------------------------------------ Teilen */
.tier-teilen {
    grid-area: 2 / 2;
    align-self: start;
    flex: none;
    width: 44px;
    height: 44px;
    margin: -10px var(--s2) 0 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    background: transparent;
    border-radius: var(--r-control);
    color: var(--ink-2);
    cursor: pointer;
}
.tier-teilen svg { width: 18px; height: 18px; }
.tier-teilen:hover { color: var(--brand); }

/* Inserted beside the button, inside a container the grid steps over, so both
   are taken out of the flow instead — in it they would land in a cell of the
   card and shove a data row aside. At the card's foot, where they cover no name. */
.tier-teilen-hinweis {
    position: absolute;
    left: var(--s4);
    right: var(--s4);
    bottom: var(--s4);
    z-index: 3;
    padding: var(--s1) var(--s2);
    font-size: var(--t-xs);
    font-weight: 600;
    text-align: center;
    background: var(--ink);
    color: var(--bg);
    border-radius: var(--r-control);
    pointer-events: none;
}
/* The address itself, selectable, where neither a share sheet nor a clipboard
   exists. Same 16-pixel floor as the search field, same reason. */
.tier-teilen-feld {
    position: absolute;
    left: var(--s4);
    right: var(--s4);
    bottom: var(--s4);
    z-index: 3;
    padding: var(--s2);
    font-family: var(--schrift-text);
    font-size: var(--t-base);
    border: 1px solid var(--line-strong);
    border-radius: var(--r-control);
    background: var(--bg-bar);
    color: var(--ink);
}

/* One animal's own page, and the card keeps a card's width there. */
.tier-seite { max-width: 26rem; }
.tier-seite .tier-gitter { grid-template-columns: minmax(0, 1fr); }
.tier-seite-heim,
.tier-seite-weiter {
    margin-top: var(--s4);
    font-size: var(--t-base);
    line-height: 1.6;
    color: var(--ink-2);
}
.tier-seite-heim a,
.tier-seite-weiter a { color: var(--brand); }

/* The scroll marker needs real height — a zero-height element never
   intersects. */
.nachlade-marke { height: 1px; }

/* ---------------------------------------------------------- group headings */
.gruppe {
    font-family: var(--schrift-titel);
    font-size: var(--t-xl);
    font-weight: 500;
    font-variation-settings: 'opsz' 24;
    line-height: 1.15;
    color: var(--ink);
    margin: var(--s7) 0 var(--s5);
    padding-bottom: var(--s3);
    border-bottom: 1px solid var(--line);
    display: flex;
    align-items: baseline;
    gap: var(--s3);
}
.gruppe:first-child { margin-top: 0; }
.gruppe-zahl {
    font-family: var(--schrift-text);
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.09em;
    color: var(--ink-2);
    font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- skeletons */
/* The geometry of the real card and nothing else — flat, and no shimmer: a
   shimmer is motion for its own sake and exactly what a reduced-motion visitor
   is asking not to see. */
.skelett {
    display: flex;
    flex-direction: column;
    gap: var(--s3);
    background: var(--bg-bar);
    border: 1px solid var(--line);
    padding-bottom: var(--s4);
}
.skelett-foto {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 5;
    background: var(--bg-sunk);
}
.skelett-zeile {
    display: block;
    height: 13px;
    margin: 0 var(--s4);
    background: var(--bg-sunk);
    border-radius: var(--r-photo);
}
.skelett-kurz { width: 55%; }

/* ============================================================ shelter list */
/* An index, not a set of cards. */
.stand {
    font-size: var(--t-xs);
    font-weight: 500;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-2);
    font-variant-numeric: tabular-nums;
    margin-bottom: var(--s5);
}

.heim-gruppe { margin-bottom: var(--s6); }

.heim-ueberschrift {
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-2);
    padding-bottom: var(--s2);
    border-bottom: 1px solid var(--line-strong);
}

.heim-liste { list-style: none; }

.heim-zeile {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s4);
    min-height: 44px;
    padding: var(--s4) var(--s2);
    border-bottom: 1px solid var(--line);
    text-decoration: none;
    color: inherit;
}
.heim-zeile:hover { background: var(--bg-sunk); }

.heim-text { display: block; min-width: 0; }
.heim-name {
    display: block;
    font-family: var(--schrift-titel);
    font-size: var(--t-md);
    font-weight: 500;
    font-variation-settings: 'opsz' 17;
    line-height: 1.25;
    color: var(--ink);
}
.heim-ort { display: block; font-size: var(--t-sm); color: var(--ink-2); }
.heim-note { display: block; font-size: var(--t-sm); color: var(--ink-2); }
.heim-zahl {
    flex: none;
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--ink-2);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
/* A shelter whose scraper actually broke becomes visible instead of hiding
   among thirty identical timestamps. */
.heim-alt,
.heim-fehler {
    font-size: var(--t-sm);
    color: var(--warn);
    padding: 0 var(--s2) var(--s3);
}

.abschnitt-note {
    font-size: var(--t-sm);
    color: var(--ink-2);
    margin: var(--s3) 0 var(--s4);
}

/* ============================================================ shelter page */
.heim-seite { max-width: 62ch; margin-bottom: var(--s6); }
.heim-titel {
    display: flex;
    align-items: center;
    gap: var(--s3);
    font-family: var(--schrift-titel);
    font-size: 2.125rem;              /* 34px */
    font-weight: 500;
    font-variation-settings: 'opsz' 34;
    line-height: 1.1;
    letter-spacing: -0.01em;
    margin-bottom: var(--s4);
}
.heim-zeichen { flex: none; display: inline-flex; color: var(--brand); }
.heim-zeichen svg { width: 24px; height: 24px; fill: currentColor; }
.heim-prosa {
    font-family: var(--schrift-titel);
    font-size: var(--t-md);
    font-weight: 400;
    font-variation-settings: 'opsz' 17;
    line-height: 1.6;
    color: var(--ink-2);
    margin-bottom: var(--s5);
}
.heim-daten {
    /* "Öffnungszeiten:" is the longest label anywhere on the site, and at 11
       pixels with this tracking it needs about 115 of them. The card's own
       narrower column would run the value straight into it. */
    --daten-spalte: 8rem;
    margin-bottom: var(--s5);
    border-top: 1px solid var(--line);
}
.heim-daten-zeile {
    padding: var(--s2) 0;
    padding-left: var(--daten-spalte);
    text-indent: calc(-1 * var(--daten-spalte));
    border-bottom: 1px solid var(--line);
    font-size: var(--t-sm);
    overflow-wrap: break-word;
}
.heim-label {
    display: inline-block;
    width: var(--daten-spalte);
    text-indent: 0;
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-2);
}
.heim-daten a { color: var(--brand); }
.heim-aktionen { margin-bottom: var(--s4); }
.heim-stand {
    font-size: var(--t-xs);
    font-weight: 500;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-2);
    font-variant-numeric: tabular-nums;
    margin-bottom: var(--s2);
}
.detail-error { color: var(--warn); margin-top: var(--s4); }

/* -------------------------------------------------------------- the map */
/* Every colour a token, which is all dark mode needs here. */
.karte-platz {
    width: 100%;
    /* The viewBox's own ratio, so the page has its height before the file
       arrives and nothing jumps when it does. */
    aspect-ratio: 987.1 / 511;
    margin-top: var(--s4);
}
.karte-platz svg {
    display: block;
    width: 100%;
    height: auto;
    /* A shelter name near the east edge reaches past the viewBox. */
    overflow: visible;
}
/* A wide enough stroke to cover the slivers where two simplified borders do
   not quite meet. */
.karte-platz [data-bl] {
    fill: var(--bg-sunk);
    stroke: var(--line-strong);
    stroke-width: 1.5;
    stroke-linejoin: round;
}
.karte-heim { cursor: pointer; }
/* The finger-sized target; the dot an eye sees is seven units. */
.karte-heim .karte-treffer { fill: none; pointer-events: all; }
.karte-heim .karte-punkt {
    fill: var(--brand);
    stroke: var(--bg);
    stroke-width: 2;
    transform-box: fill-box;
    transform-origin: center;
    transition: transform var(--motion);
}
.karte-heim:hover .karte-punkt,
.karte-heim:focus-visible .karte-punkt { transform: scale(1.6); }
/* The name on hover and focus only: thirty at once would be the list, drawn
   worse. The stroke under the letters keeps them readable where they cross a
   border. */
.karte-heim .karte-name {
    display: none;
    font-family: var(--schrift-titel);
    font-size: 26px;
    font-variation-settings: 'opsz' 26;
    font-weight: 600;
    text-anchor: middle;
    fill: var(--ink);
    paint-order: stroke;
    stroke: var(--bg);
    stroke-width: 6px;
    stroke-linejoin: round;
    pointer-events: none;
}
.karte-heim:hover .karte-name,
.karte-heim:focus-visible .karte-name { display: block; }
.karte-quelle {
    margin-top: var(--s3);
    font-size: var(--t-xs);
    color: var(--ink-2);
}
.karte-quelle a { color: inherit; }
/* The strip is display:flex, which outweighs the hidden attribute the map face
   sets on the filter row, so the attribute needs its own heavier rule. */
#shelterFilters[hidden] { display: none; }

/* ------------------------------------------------- empty states and errors */
/* An empty screen is an invitation, not a dead end. */
.leer { padding: var(--s7) 0; max-width: 52ch; }
.leer p {
    font-family: var(--schrift-titel);
    font-size: var(--t-lg);
    font-weight: 400;
    font-variation-settings: 'opsz' 20;
    line-height: 1.4;
    margin-bottom: var(--s4);
}
.leer-aktionen { display: flex; gap: var(--s3); flex-wrap: wrap; margin-bottom: var(--s4); }
.leer-hinweis {
    font-family: var(--schrift-text);
    font-size: var(--t-sm);
    color: var(--ink-2);
}

.fehler-box { padding: var(--s7) 0; max-width: 52ch; }
.fehler-box p { color: var(--warn); margin-bottom: var(--s5); }
.fehler-aktionen { display: flex; gap: var(--s3); flex-wrap: wrap; }
.fehler-aktionen .btn-more { margin: 0; }

/* =============================================== konto, forms and Merkliste */
/* One measure for a form. A field wider than the reading measure is harder to
   scan, not easier. */
.konto-panel { max-width: 56ch; padding-top: var(--s5); }

/* Two of those pages are not forms. "Meine Tiere" and a shared list hold a
   `.tier-gitter`, whose column count is chosen from the viewport and not from
   the box it stands in: at 1280 that is four columns, and inside 56ch each card
   is about 104 pixels — less than `.tier-alter`'s label column alone, so every
   value overflows and every name collapses to an ellipsis. Both take the full
   measure. */
.konto-panel:has(#merk-seite),
.konto-panel:has(#liste-seite) { max-width: var(--spalte); }

.konto-panel h2 {
    font-family: var(--schrift-titel);
    font-size: 2.125rem;              /* 34px */
    font-weight: 500;
    font-variation-settings: 'opsz' 34;
    line-height: 1.1;
    margin-bottom: var(--s4);
}
.konto-prosa {
    font-family: var(--schrift-titel);
    font-size: var(--t-md);
    font-weight: 400;
    font-variation-settings: 'opsz' 17;
    line-height: 1.6;
    color: var(--ink-2);
    margin-bottom: var(--s5);
    overflow-wrap: anywhere;   /* the e-mail addresses in this prose */
}

.feld { display: block; margin-bottom: var(--s5); }
.feld-label {
    display: block;
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-2);
    margin-bottom: var(--s2);
}
.feld-hinweis { display: block; font-size: var(--t-sm); color: var(--ink-2); margin-top: var(--s2); }
/* The same 16-pixel floor as the search field, and for the same reason. */
.feld-eingabe {
    font-family: var(--schrift-text);
    font-size: var(--t-base);
    color: var(--ink);
    background: var(--bg-bar);
    border: 1px solid var(--line-strong);
    border-radius: var(--r-control);
    padding: 0 var(--s3);
    height: 48px;
    width: 100%;
}
.feld-eingabe:hover { border-color: var(--ink-2); }
.feld-eingabe::placeholder { color: var(--ink-2); opacity: 1; }

/* A real <form> only so that Enter submits: the content policy refuses the
   submit itself and a delegated listener sends the fields instead. */
.konto-form { display: block; }
.konto-aktionen { display: flex; gap: var(--s3); flex-wrap: wrap; margin-top: var(--s6); }
.konto-wechsel { margin-top: var(--s6); font-size: var(--t-sm); color: var(--ink-2); }
.konto-wechsel a { color: var(--brand); }
/* Errors and confirmations sit above the buttons, where the eye already is
   after the last field. */
.konto-fehler { color: var(--warn); margin-top: var(--s4); }
.konto-ok { color: var(--zweit); margin-top: var(--s4); }
.konto-gefahr { margin-top: var(--s7); padding-top: var(--s5); border-top: 1px solid var(--line-strong); }
.konto-gefahr .btn-rand { color: var(--warn); border-color: var(--warn); }
.konto-gefahr .btn-rand:hover { background: var(--bg-sunk); border-color: var(--warn); }

.konto-admin { margin-top: var(--s6); padding-top: var(--s5); border-top: 1px solid var(--line); }
.konto-admin-titel,
.konto-abschnitt-titel {
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-2);
}
/* The address block's own heading (OP217). Spaced here because it stands
   straight in the panel, where the Admin heading has a <section> around it. */
.konto-abschnitt-titel { margin-bottom: var(--s3); }
.konto-admin-liste { list-style: none; margin-top: var(--s3); }
.konto-admin-liste li { margin-top: var(--s2); font-size: var(--t-sm); }
/* 44 pixels, like every other link that is really a control: a bare run of
   text is fifteen pixels high and cannot be hit with a thumb. */
.konto-admin-liste a { min-height: 44px; display: inline-flex; align-items: center; color: var(--brand); }
.konto-admin-was { display: block; color: var(--ink-2); font-size: var(--t-xs); }

/* --------------------------------------------------------- the named lists */
.merk-abschnitt { margin-top: var(--s7); }
.merk-titel {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--s3);
    font-family: var(--schrift-titel);
    font-size: var(--t-xl);
    font-weight: 500;
    font-variation-settings: 'opsz' 24;
    line-height: 1.15;
    padding-bottom: var(--s3);
    margin-bottom: var(--s4);
    border-bottom: 1px solid var(--line-strong);
}
.merk-titel-wort { min-width: 0; overflow-wrap: break-word; }
.merk-unter { font-size: var(--t-sm); color: var(--ink-2); margin-bottom: var(--s5); }
/* Tabular figures, so the heading does not jiggle sideways when a card is
   taken away and 10 becomes 9. */
.merk-zahl {
    font-family: var(--schrift-text);
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.09em;
    color: var(--ink-2);
    font-variant-numeric: tabular-nums;
}
.merk-geteilt {
    font-family: var(--schrift-text);
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--zweit);
    border: 1px solid var(--zweit);
    border-radius: var(--r-control);
    padding: 2px var(--s2);
}

/* Ghosts until they are wanted: a control that carries a border of its own
   at rest turns a page of tiles into a page of buttons. */
.listen-werkzeug { display: inline-flex; gap: var(--s1); margin-left: auto; }
.listen-icon,
.listen-menue-knopf {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: 1px solid transparent;
    border-radius: var(--r-control);
    color: var(--ink-2);
    cursor: pointer;
}
.listen-icon { width: 44px; height: 44px; }
.listen-icon svg,
.listen-menue-knopf svg { width: 20px; height: 20px; flex: none; }
.listen-icon:hover,
.listen-menue-knopf:hover { color: var(--brand); border-color: var(--line-strong); }
.listen-icon.an { color: var(--zweit); border-color: var(--zweit); }
.listen-icon-weg { color: var(--warn); }
.listen-icon-weg:hover { color: var(--warn); border-color: var(--warn); }

/* "Liste löschen?" and its two answers. Never a browser dialog. */
.listen-frage {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--s3);
    padding: var(--s3) var(--s4);
    margin-bottom: var(--s4);
    background: var(--bg-sunk);
    border-left: 3px solid var(--warn);
    border-radius: var(--r-control);
    font-size: var(--t-sm);
}
/* The public address of a shared list. It can be seventy unbroken characters,
   and without this it is the one thing on the page that scrolls a phone
   sideways. */
.listen-adresse {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--s3);
    font-size: var(--t-sm);
    color: var(--ink-2);
    margin-bottom: var(--s4);
    overflow-wrap: anywhere;
}
.listen-adresse a { color: var(--brand); }

/* The drop rail sticks under the masthead, so a card can be dragged onto a
   list without scrolling back up first — and it sticks on konto.js's wrapper,
   never on the row: a sticky box travels only inside its containing block,
   and the row's is exactly as tall as the row. */
#listen-dock {
    position: sticky;
    top: 56px;
    z-index: 20;
    margin-bottom: var(--s4);
    background: var(--bg);
}
.listen-dock {
    display: flex;
    gap: var(--s2);
    padding: var(--s3) 0;
    border-bottom: 1px solid var(--line);
    overflow-x: auto;
    scrollbar-width: none;
}
.listen-dock::-webkit-scrollbar { display: none; }
.listen-dock-ziel,
.listen-dock-neu {
    flex: none;
    min-height: 44px;
    padding: 0 var(--s4);
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    font-family: var(--schrift-text);
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    white-space: nowrap;
    background: var(--bg-bar);
    color: var(--ink-2);
    border: 1px solid var(--line-strong);
    border-radius: var(--r-control);
    cursor: pointer;
}
.listen-dock-ziel:hover,
.listen-dock-neu:hover { color: var(--brand); border-color: var(--brand); }
.listen-dock-ziel.dock-an { background: var(--brand); color: var(--on-brand); border-color: var(--brand); }
/* A drag is on: every target says so, and the one under the pointer says it
   twice. A dashed edge rather than a fill, so the words stay readable. */
body[data-zieht="1"] .listen-dock-ziel,
body[data-zieht="1"] .listen-dock-neu { border-style: dashed; border-color: var(--brand); }
.listen-dock-ziel.dock-ueber {
    background: var(--brand);
    color: var(--on-brand);
    border-style: solid;
    border-color: var(--brand);
}
/* The card being dragged. Never opacity alone — a half-transparent card over a
   list of solid ones reads as broken rather than as moving. */
.tier.zieht { border-color: var(--brand); transform: scale(0.98); }

/* ------------------------------------------- the tile's own way onto a list */
/* What a finger does by dragging, a keyboard and a screen reader do here.
   konto.js appends the block as the tile's `zusatz`, so it arrives as a direct
   child of the card and needs a row of its own — without one the grid would
   auto-place it in the first free cell, which is the gap under the name.

   It replaces a stack of checkboxes that stood open under every tile, and
   that stack is the clunkiness this page was asked to lose. */
.listen-tiermenue {
    grid-area: 10 / 1 / 11 / 3;
    position: relative;
    padding: var(--s2) var(--s4) 0;
}
.listen-menue-knopf {
    gap: var(--s2);
    padding: 0 var(--s3) 0 var(--s2);
    font-family: var(--schrift-text);
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}

/* The menu stands over the card and never inside its flow: pushing the card
   taller would move every tile below it while somebody is aiming at a row.
   Upwards, because the button sits at the card's foot and a menu dropping the
   other way would cover the next card instead of this one's own data list.
   There are no shadows in this look, so the plate's own tone and its hairline
   are the whole edge — and that tone has to be the sunk one, because the card
   underneath is already --bg-bar and the menu would vanish into it. */
.listen-menue {
    position: absolute;
    left: var(--s4);
    right: var(--s4);
    bottom: calc(100% - var(--s2));
    z-index: 6;
    max-height: 15rem;
    overflow-y: auto;
    padding: var(--s1);
    background: var(--bg-sunk);
    border: 1px solid var(--line-strong);
    border-radius: var(--r-control);
}
/* konto.js shuts it with the attribute alone, and any display outranks it. */
.listen-menue[hidden] { display: none; }
/* An open menu leaves its own card, and the next card is a later sibling that
   would paint straight over it. */
.tier:has(.listen-menue:not([hidden])) { z-index: 6; }
/* `content-visibility` brings paint containment with it, and paint containment
   clips whatever leaves the card — this menu among it. The lists page holds a
   handful of tiles and not 1420, so a card that carries a menu gives the
   rendering trick up rather than the menu. */
.tier:has(.listen-tiermenue) { content-visibility: visible; contain-intrinsic-size: none; }

.listen-menue-wahl {
    display: flex;
    align-items: center;
    gap: var(--s3);
    min-height: 44px;
    padding: 0 var(--s2);
    border-radius: var(--r-photo);
    font-size: var(--t-sm);
    color: var(--ink);
    cursor: pointer;
}
.listen-menue-wahl:hover { background: var(--bg-bar); }
.listen-menue-wahl input { width: 18px; height: 18px; flex: none; accent-color: var(--brand); }

/* ------------------------------------------------------------------ footer */
footer {
    max-width: var(--spalte);
    margin: var(--s7) auto 0;
    padding: var(--s5) var(--s4) var(--s6);
    border-top: 1px solid var(--line);
    font-size: var(--t-sm);
    color: var(--ink-2);
}
footer p { margin-bottom: var(--s1); }
footer a {
    color: var(--brand);
    display: inline-flex;
    align-items: center;
    min-height: 44px;
}
/* First in the markup, because a float has to precede what wraps around it. */
.fuss-impressum { float: right; margin-left: var(--s5); }

/* ====================================================== 640px and above ==== */
@media (min-width: 640px) {
    .wortmarke { font-size: var(--t-lg); font-variation-settings: 'opsz' 20; }
    .wortmarke-land { display: inline; }
    .pfote { width: 22px; height: 22px; }
}

/* ====================================================== 700px and above ==== */
@media (min-width: 700px) {
    .tier-gitter { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .chip-panel { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .willkommen-wege { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ===================================================== 1024px and above ==== */
@media (min-width: 1024px) {
    /* The masthead grows its second row, so anything jumped to has to clear
       both: 56 plus 48, plus a little air. */
    html { scroll-padding-top: 120px; }

    /* No bar at the foot of the screen, so the body owes it no room. */
    body { padding-bottom: 0; }

    /* Row one carries the account word and the colour scheme on either side
       of the wordmark, so the wordmark centres without a magic offset. */
    .kopf-innen {
        height: auto;
        padding: 0 var(--s6);
        grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
        grid-template-rows: 56px auto;
        align-items: center;
    }
    .wortmarke {
        grid-area: 1 / 2;
        justify-self: center;
        font-size: var(--t-xl);
        font-variation-settings: 'opsz' 24;
        letter-spacing: 0;
    }
    .kopf-konto { grid-area: 1 / 1; justify-self: start; }
    /* The pair, not the single button: the look switch stands beside the
       colour-scheme one since 2026-08-04 and they share the cell. */
    .kopf-tasten { grid-area: 1 / 3; justify-self: end; }

    .ansichten {
        position: static;
        grid-area: 2 / 1 / 3 / 4;
        justify-content: center;
        gap: var(--s6);
        background: none;
        border-top: 1px solid var(--line);
        padding-bottom: 0;
        overflow-x: visible;
    }
    .navitem {
        flex: none;
        min-width: 0;
        min-height: 48px;
        font-size: var(--t-xs);
        border-top: 0;
        border-bottom: 2px solid transparent;
    }
    .navitem:hover { color: var(--ink); }
    .navitem.aktiv { border-top-color: transparent; border-bottom-color: var(--brand); }

    .ergebnis-leiste { padding: var(--s7) var(--s6) var(--s6); }
    .ergebnis { font-size: 1.75rem; font-variation-settings: 'opsz' 28; max-width: 40ch; }
    .ansicht-kopf { padding: 0 var(--s6); }
    .kopf-zeile { padding: 0; }

    main { padding: 0 var(--s6) var(--s7); }
    footer { padding: var(--s5) var(--s6) var(--s6); }

    /* At the full 1080 measure a card is 317 wide and its photograph 317 by
       396 — the size this look was drawn for. */
    .tier-gitter {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        column-gap: var(--s5);
        row-gap: var(--s7);
    }

    .willkommen-kopf { display: flex; align-items: flex-start; gap: var(--s7); }
    .willkommen-links { flex: none; max-width: 22rem; }
    .willkommen-punkte { flex: 1; min-width: 0; }
    .willkommen-titel { font-size: 3rem; font-variation-settings: 'opsz' 48; }
    .heim-titel { font-size: 2.75rem; font-variation-settings: 'opsz' 44; }

    /* The drop rail clears the taller masthead. */
    #listen-dock { top: 105px; }
}

/* ===================================================== 1280px and above ==== */
/* The one wide step, and it touches nothing below itself: the measure grows
   only here, so a 1024 laptop keeps the three-card page it had. 1420 is 1340
   of content between 40-pixel margins — four cards of 317 with three 24-pixel
   gutters, the very card the three-card row draws at the 1080 measure. A 1280
   screen has not reached the measure and draws them at 282, a shade under the
   298 the three-card row already draws at 1024. */
@media (min-width: 1280px) {
    :root { --spalte: 1420px; }
    .tier-gitter { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ======================================================= under 700px ==== */
/* The phone, and the one place in this file that is written the other way
   round — a `max-width` block, after everything it changes. Georg, 2026-08-04:
   "on the mobile it is far from ideal, the pictures are huge and it is annoying
   to scroll".
 *
 * He was right, and the arithmetic says why: this look was drawn for a
 * 317-pixel column, and at 360 the same card is 328 wide with a 328 by 410
 * photograph over five data rows. That is a card 620 pixels tall — one animal
 * per screen, and 1420 of them to scroll past.
 *
 * So under 700 pixels the lists wear one of two layouts, and a switch above
 * them picks. Both show about four animals per screen instead of one, and both
 * keep every field the wide card carries — the breed, the age, the shelter and
 * how long the animal has been waiting:
 *
 *   Karten  two cards to a row, the same card at half the width. The default,
 *           and Georg's pick of the two.
 *   Zeile   one animal per row: the photograph 112 pixels wide on the left,
 *           the four lines stacked beside it.
 *
 * What both give up is the label column — "ALTER", "TIERHEIM" — and the date
 * beside the waiting time. At this width the uppercase label is wider than
 * the value it labels, and "3 Jahre" and a shelter's name in plum read as what
 * they are without one. The hairline between two rows goes with them: on a
 * card this small five hairlines are a fence, not a data list.
 *
 * One card is left alone: the single animal on its own page, `.tier-seite`,
 * which is one card on an empty screen with nothing to scroll past. That is
 * what every `:not(.tier-seite) >` below is for.
 *
 * The switch itself is drawn by filter.js, and only where <html> carries
 * data-handy-wahl — gestaltung.py decides that, so no script knows a look by
 * name. It writes data-handy="karten" or data-handy="zeile" beside it; with
 * neither, this block draws Karten.
 */

/* Above 700 there is one layout and nothing to choose. filter.js still fills
   the switch — this is what keeps it off a desktop screen. */
.handy-wahl { display: none; }

@media (max-width: 699px) {

/* --------------------------------------------------------------- the switch */
/* `:not([hidden])` rather than the class alone: the element ships with the
   hidden attribute and the reset's own `[hidden]` rule would otherwise win on
   order. */
.handy-wahl:not([hidden]) {
    display: flex;
    align-items: center;
    gap: var(--s2);
    margin-top: var(--s3);
}
.handy-wort {
    flex: none;
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-2);
}

/* ------------------------------------------------- what both layouts share */
:not(.tier-seite) > .tier-gitter > .tier {
    /* The card is a third of the height it had, and the browser's guess for an
       off-screen one has to follow, or the scrollbar lies for 1420 animals. */
    contain-intrinsic-size: auto 340px;
    padding-bottom: var(--s3);
}
:not(.tier-seite) > .tier-gitter > .tier .tier-name {
    padding-left: var(--s3);
    font-size: var(--t-md);
    font-variation-settings: 'opsz' 17;
}
:not(.tier-seite) > .tier-gitter > .tier .tier-rasse-wort {
    padding: 0 var(--s3) var(--s1);
    font-size: var(--t-sm);
}
/* The label column and the hairlines, gone together. */
:not(.tier-seite) > .tier-gitter > .tier .tier-alter::before,
:not(.tier-seite) > .tier-gitter > .tier .tier-fuss::before,
:not(.tier-seite) > .tier-gitter > .tier .tier-marke::before {
    display: none;
}
:not(.tier-seite) > .tier-gitter > .tier .tier-alter,
:not(.tier-seite) > .tier-gitter > .tier .tier-fuss,
:not(.tier-seite) > .tier-gitter > .tier .tier-zeit,
:not(.tier-seite) > .tier-gitter > .tier .tier-stoerung,
:not(.tier-seite) > .tier-gitter > .tier .tier-marke {
    border-top: 0;
    padding: 1px var(--s3);
    text-indent: 0;
    line-height: 1.35;
}
/* The short word down here, out of the paragraph's own attribute. A Karten
   card is about 156 pixels wide at 360, where "Website derzeit nicht
   erreichbar" is three lines under a photograph that is already the tallest
   thing on the card. The long word stays the paragraph's text, which is what a
   screen reader reads. */
:not(.tier-seite) > .tier-gitter > .tier .tier-stoerung { font-size: 0; }
:not(.tier-seite) > .tier-gitter > .tier .tier-stoerung::before {
    content: attr(data-kurz);
    font-size: var(--t-xs);
    font-weight: 600;
}
/* The age is the one line that would read as a stray number without its
   label, so it keeps a word — the one the label used to carry. */
:not(.tier-seite) > .tier-gitter > .tier .tier-alter::after {
    content: " alt";
    color: var(--ink-2);
}
/* Two lines and then dots. "Tierschutz Austria (Tierschutzhaus Vösendorf),
   Niederösterreich" is the longest shelter name on the site and it wrapped to
   four lines on a card 156 wide — taller than the photograph above it, and it
   is the least interesting fact on the card. The link still leads to the
   shelter's own page, where the whole name stands. */
:not(.tier-seite) > .tier-gitter > .tier .tier-fuss {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
}
:not(.tier-seite) > .tier-gitter > .tier .tier-marke {
    justify-content: flex-start;
    font-size: var(--t-xs);
}
:not(.tier-seite) > .tier-gitter > .tier .tier-fund-hinweis,
:not(.tier-seite) > .tier-gitter > .tier .tier-vermittlung-hinweis {
    margin: var(--s1) var(--s3) 0;
    padding: var(--s1) var(--s2);
    font-size: var(--t-xs);
}
/* Still a 44-pixel target, and it stops being 44 pixels of ink: the icon and
   the box it sits in are two different sizes, and only the box has to be big
   enough for a thumb. */
:not(.tier-seite) > .tier-gitter > .tier .tier-teilen {
    width: 40px;
    height: 40px;
    margin: -8px 0 0 0;
}

/* ------------------------------------------------------------------ Karten */
/* Two to a row. Nothing else changes: it is the card above at half the width,
   which is what makes it the cheap layout of the two. */
:root:not([data-handy="zeile"]) :not(.tier-seite) > .tier-gitter {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--s3);
    row-gap: var(--s5);
}

/* ------------------------------------------------------------------- Zeile */
/* One animal per row. The photograph keeps its 4:5 — the standing portrait is
   the look — and is 112 wide, so it is 140 tall and the four lines beside it
   come out level with it. */
:root[data-handy="zeile"] { --handy-foto: 112px; }

:root[data-handy="zeile"] :not(.tier-seite) > .tier-gitter {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--s4);
}
:root[data-handy="zeile"] :not(.tier-seite) > .tier-gitter > .tier {
    grid-template-columns: var(--handy-foto) minmax(0, 1fr) auto;
    contain-intrinsic-size: auto 168px;
    padding-bottom: var(--s2);
}
/* The photograph takes the whole left column. `align-self: start` is what
   keeps the box the height of the picture rather than the height of the row —
   the found-animal band hangs on that box's bottom edge, and stretched it
   would float somewhere under the photograph. */
:root[data-handy="zeile"] :not(.tier-seite) > .tier-gitter > .tier .tier-haupt {
    grid-area: 1 / 1 / 10 / 2;
    align-self: start;
    margin-bottom: 0;
}
/* The heart is a child of the card, not of the photograph, so on this layout
   it has to be told where the photograph's top right corner is. */
:root[data-handy="zeile"] :not(.tier-seite) > .tier-gitter > .tier .tier-merken {
    right: auto;
    left: calc(var(--handy-foto) - 44px);
}
:root[data-handy="zeile"] :not(.tier-seite) > .tier-gitter > .tier .tier-name {
    grid-area: 1 / 2 / 2 / 3;
    padding-top: var(--s2);
    font-size: var(--t-lg);
    font-variation-settings: 'opsz' 20;
}
:root[data-handy="zeile"] :not(.tier-seite) > .tier-gitter > .tier .tier-teilen {
    grid-area: 1 / 3 / 2 / 4;
    margin: var(--s1) 0 0 0;
}
:root[data-handy="zeile"] :not(.tier-seite) > .tier-gitter > .tier .tier-fund-hinweis,
:root[data-handy="zeile"] :not(.tier-seite) > .tier-gitter > .tier .tier-vermittlung-hinweis {
    grid-area: 2 / 2 / 3 / 4;
}
:root[data-handy="zeile"] :not(.tier-seite) > .tier-gitter > .tier .tier-rasse-wort {
    grid-area: 3 / 2 / 4 / 4;
}
:root[data-handy="zeile"] :not(.tier-seite) > .tier-gitter > .tier .tier-alter {
    grid-area: 4 / 2 / 5 / 4;
}
/* Every child here carries a full `grid-area` reaching into column 4, so the
   four rules below move together. A bare `grid-row` on the new line would
   leave its column to auto-placement and the share control's third column
   would cut it short; the photograph's `1 / 1 / 10 / 2` still covers all of
   them. */
:root[data-handy="zeile"] :not(.tier-seite) > .tier-gitter > .tier .tier-fuss {
    grid-area: 5 / 2 / 6 / 4;
}
:root[data-handy="zeile"] :not(.tier-seite) > .tier-gitter > .tier .tier-stoerung {
    grid-area: 6 / 2 / 7 / 4;
}
:root[data-handy="zeile"] :not(.tier-seite) > .tier-gitter > .tier .tier-marke {
    grid-area: 7 / 2 / 8 / 4;
}
:root[data-handy="zeile"] :not(.tier-seite) > .tier-gitter > .tier .tier-zeit {
    grid-area: 8 / 2 / 9 / 4;
}
/* The skeleton is the geometry of the real card, so it turns into a row with
   the rest. */
:root[data-handy="zeile"] .skelett {
    display: grid;
    grid-template-columns: var(--handy-foto) minmax(0, 1fr);
    column-gap: 0;
    align-items: start;
    padding-bottom: var(--s2);
}
:root[data-handy="zeile"] .skelett-foto { grid-area: 1 / 1 / 4 / 2; }
:root[data-handy="zeile"] .skelett-zeile { margin: var(--s3) var(--s3) 0; }

}
