/*
 * Shared base: typography, grid skeleton, components.
 *
 * Design variants (theme-a/b/c.css) rearrange the grid areas and change
 * colours. They never redefine components, so a variant is a small file.
 *
 * Half the traffic is phones and tablets, so type sizing here is a requirement
 * rather than a preference: nothing drops below 16px, body text runs 17px on
 * mobile and 18px from tablet up.
 *
 * Bootstrap is configured through its own custom properties instead of being
 * overridden with !important — fighting the framework is what made the earlier
 * prototype unmaintainable.
 */

/* ---------------------------------------------------------------- typography */

:root {
    --bs-body-font-family: system-ui, -apple-system, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
    --bs-body-font-size: 1.0625rem;   /* 17px */
    --bs-body-line-height: 1.7;

    --ik-tap: 2.75rem;                /* 44px touch target */
    --ik-radius: 0.5rem;
    --ik-gap: clamp(1rem, 3vw, 2rem);
    --ik-page-max: 78rem;
    --ik-heading-family: var(--bs-body-font-family);
}

@media (min-width: 768px) {
    :root { --bs-body-font-size: 1.125rem; } /* 18px */
}

body {
    text-rendering: optimizeLegibility;
    -webkit-text-size-adjust: 100%;
}

h1, h2, h3, h4 {
    font-family: var(--ik-heading-family);
    line-height: 1.2;
    text-wrap: balance;
    margin-bottom: 0.55em;
}

h1 { font-size: clamp(1.75rem, 1.25rem + 2.4vw, 2.6rem); }
h2 { font-size: clamp(1.375rem, 1.1rem + 1.4vw, 1.9rem); }
h3 { font-size: clamp(1.1875rem, 1.05rem + 0.7vw, 1.45rem); }

h2, h3 { margin-top: 1.8em; }
h2:first-child, h3:first-child { margin-top: 0; }

/* ------------------------------------------------------------ grid skeleton */

/*
 * One grid, five named areas. Each variant redefines the arrangement — that is
 * what makes them different layouts rather than recolours.
 */
.ik-page {
    display: grid;
    grid-template-areas:
        "logo"
        "banner"
        "nav"
        "main"
        "foot";
    grid-template-columns: minmax(0, 1fr);
    max-width: var(--ik-page-max);
    margin-inline: auto;
}

.ik-logo { grid-area: logo; }
.ik-banner { grid-area: banner; position: relative; }
.ik-banner__overlay { display: none; }
.ik-nav-wrap { grid-area: nav; }
.ik-main { grid-area: main; min-width: 0; padding: var(--ik-gap); }
.ik-aside { grid-area: aside; display: none; }
.ik-foot { grid-area: foot; }

/*
 * Phones bring half the traffic but virtually no revenue — the Invia cookie is
 * per browser, so researching on a phone and booking on a desktop breaks
 * attribution. Wide screens therefore keep a column for tour search and offers
 * (phases 7 and 9); narrow ones stay lean for reading.
 */
@media (min-width: 992px) {
    .ik-page {
        grid-template-areas:
            "logo   logo"
            "banner banner"
            "nav    nav"
            "main   aside"
            "foot   foot";
        grid-template-columns: minmax(0, 1fr) 19rem;
    }

    .ik-aside {
        display: block;
        padding: var(--ik-gap) var(--ik-gap) var(--ik-gap) 0;
    }

    /* While the column is empty the content should use the full width. */
    .ik-page:has(.ik-aside:empty) {
        grid-template-columns: minmax(0, 1fr) 0;
    }

    .ik-aside:empty { padding: 0; }
}

/*
 * Temporary AdSense placement (faze-09-monetizace.md, 9B revision) — end of
 * content on article/beach/tourist-object pages, all widths. Reserves space
 * before the ad script resolves so it never shifts layout below it (CLS).
 */
.ik-ad {
    max-width: 728px;
    margin-inline: auto;
}

.ik-ad .adsbygoogle { min-height: 100px; }

/* ------------------------------------------------------------------- banner */

.ik-banner__link { display: block; }

.ik-banner img {
    display: block;
    width: 100%;
    /*
     * Poměr drží box i než se obrázek načte, takže nevzniká posun layoutu (CLS).
     * `cover` zůstává i teď, kdy mají Kréta i Rhodos banner ve stejném poměru
     * 2496×343 — příští ostrov nemusí mít fotku, která na tenhle poměr sedne
     * beze zbytku.
     */
    aspect-ratio: 2496 / 343;
    height: auto;
    object-fit: cover;
}

/* ---------------------------------------------------------------- navigation */

.ik-nav .navbar { padding-block: 0; }

/* Ten top-level items with icons need about 1250px. Rather than let the last
   one fall off the edge, the bar wraps to a second line when it has to. */
.ik-nav .navbar-nav { flex-wrap: wrap; }

/*
 * Bootstrap's default navbar link colour is white at 55% opacity, which lands
 * around 4:1 on a dark bar — legible in a screenshot, tiring on a phone in
 * daylight. These raise it well past the 4.5:1 minimum.
 */
.ik-nav .navbar[data-bs-theme="dark"] {
    --bs-navbar-color: rgba(255, 255, 255, 0.92);
    --bs-navbar-hover-color: #ffffff;
    --bs-navbar-active-color: #ffffff;
    --bs-navbar-brand-color: #ffffff;
    --bs-navbar-brand-hover-color: #ffffff;
    --bs-navbar-toggler-border-color: rgba(255, 255, 255, 0.3);
}

.ik-nav .navbar[data-bs-theme="light"] {
    --bs-navbar-color: var(--bs-body-color);
    --bs-navbar-hover-color: var(--bs-link-hover-color);
    --bs-navbar-active-color: var(--bs-link-color);
    --bs-navbar-brand-color: var(--bs-body-color);
}

/* Menu links need a real touch area — the old site's were about half this and
   relied on hover, which does not exist on a touchscreen. */
.ik-nav .nav-link,
.ik-nav .dropdown-item {
    min-height: var(--ik-tap);
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* Nav links get their own, slightly smaller size: at body text size (17-18px)
   ten items in one bar read as shouting. Padding still meets the 44px tap
   target — thumbs don't measure by font-size. */
.ik-nav .nav-link {
    font-size: 0.9375rem;
    padding-inline: 1.35rem;
}

.ik-nav .nav-link[aria-current="page"] {
    font-weight: 600;
    box-shadow: inset 0 -3px 0 var(--ik-accent);
}

/*
 * Nested dropdowns.
 *
 * The menu goes four levels deep (Dovolená → Zájezdy do jiných zemí → Bali →
 * Kuta Beach) and Bootstrap has no submenus of its own — this reproduces the
 * prototype's own approach: a sideways flyout wherever a pointer can hover,
 * and an indented inline branch wherever it can't (a touchscreen has no
 * hover; menu.js opens the branch on tap there instead).
 *
 * A flyout that is taller than the screen (the "Zájezdy do jiných zemí"
 * branch is 19 items, ~730px) gets its own internal scrollbar rather than
 * running off the bottom edge — the prototype does not handle this case, and
 * without it that one branch is unusable on anything shorter than a large
 * desktop display.
 */
.ik-has-sub > .dropdown-item {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
}

.ik-sub-caret {
    opacity: 0.55;
    transition: transform 0.15s ease;
}

/* Mobile / no-hover default: expand indented, in place. */
.ik-submenu {
    display: none;
    position: static;
    float: none;
    margin: 0 0 0.25rem 1rem;
    padding: 0.15rem 0 0.15rem 0.5rem;
    border: 0;
    border-left: 2px solid currentColor;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    opacity: 0.9;
}

.ik-has-sub.is-open > .ik-submenu,
.ik-has-sub:focus-within > .ik-submenu { display: block; }

.ik-has-sub.is-open > .dropdown-item .ik-sub-caret,
.ik-has-sub:focus-within > .dropdown-item .ik-sub-caret { transform: rotate(90deg); }

/* Deeper levels are progressively smaller, so nesting reads at a glance. */
.ik-submenu .dropdown-item { font-size: 0.9375rem; }
.ik-submenu .ik-submenu .dropdown-item { font-size: 0.875rem; }

/* Desktop with a real pointer: fly out to the side instead, like the
   prototype. The top-level dropdown must not clip overflow here, or the
   flyout — its descendant — gets cut off at the dropdown's own edge. */
@media (hover: hover) and (pointer: fine) {
    .ik-submenu {
        position: absolute;
        top: 0;
        left: 100%;
        display: none;
        margin: 0;
        padding: 0;
        border: var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);
        border-radius: var(--bs-dropdown-border-radius);
        background: var(--bs-dropdown-bg);
        box-shadow: var(--bs-dropdown-box-shadow);
        opacity: 1;
        width: max-content;
        min-width: 10rem;
        max-width: min(22rem, calc(100vw - 2rem));
        max-height: min(75vh, 30rem);
        overflow-y: auto;
        overflow-x: hidden;
    }

    .ik-has-sub:hover > .ik-submenu,
    .ik-has-sub:focus-within > .ik-submenu { display: block; }

    .ik-has-sub:hover > .dropdown-item .ik-sub-caret,
    .ik-has-sub:focus-within > .dropdown-item .ik-sub-caret { transform: none; }

    /* A third level flies out forward too (same left:100% as the base rule),
       not back over the second level's own parent — opening backward landed
       it in the exact same rectangle as the first column, indistinguishable
       from it even once visible. */

    /*
     * A submenu that itself contains a flyout must not clip in x, or that
     * flyout — its descendant, positioned via left:100% outside its own box —
     * gets cut off at this submenu's edge despite computing a correct
     * position. Only "Zájezdy do jiných zemí" and similar match this; leaf
     * submenus keep their scroll/clip as before.
     *
     * overflow-x and overflow-y cannot be mixed here (a lone "visible" on one
     * axis computes back to "auto", per the CSS Overflow spec) — visible has
     * to apply to both, so max-height goes too: with it still set, content
     * past that height painted outside the box's own background, which is
     * exactly the bug this menu shipped with (background stopping partway
     * through a long branch, e.g. after "Seychely" in this one). Without a
     * height cap the box just grows to fit its content instead.
     */
    .ik-submenu:has(.ik-submenu) {
        overflow: visible;
        max-height: none;
    }

    .ik-submenu .dropdown-item { font-size: inherit; }
    .ik-submenu .ik-submenu .dropdown-item { font-size: inherit; }
}

/*
 * Width follows content, not one fixed number for every branch — "Pláže"
 * has ten one-word labels and does not need the same width as a branch full
 * of "Letovisko {name}" or region labels. max-width keeps a single long
 * label from stretching the box past a sane point; word-break below wraps
 * it instead. 22rem comfortably fits even the longest four-region Crete
 * label ("Zájezdy - Jižní pobřeží Kréty", ~264px unwrapped, measured against
 * the live menu) without needing a fixed width for every other branch too.
 */
.navbar .dropdown-menu {
    width: max-content;
    min-width: 10rem;
    max-width: min(22rem, calc(100vw - 2rem));
}

/* Deep labels must wrap rather than widen the menu. */
.navbar .dropdown-item {
    white-space: normal;
    word-break: break-word;
}

.ik-icon {
    width: 1.1em;
    height: 1.1em;
    flex: 0 0 auto;
    fill: currentColor;
    opacity: 0.7;
}

/* --------------------------------------------------------------- components */

/*
 * Card. The base carries the box behaviour so a theme only has to restyle it;
 * leaving it to themes once left variant A rendering cards as inline
 * underlined text.
 */
.ik-card {
    display: block;
    padding: 1.1rem 1.25rem;
    border-radius: var(--ik-radius);
    text-decoration: none;
    color: inherit;
}

.ik-card__title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 600;
    margin-bottom: 0.15rem;
}

.ik-prose > * + * { margin-top: 1.05em; }
.ik-prose img { max-width: 100%; height: auto; }

.ik-panel {
    background: var(--ik-surface);
    border: 1px solid var(--bs-border-color);
    border-radius: var(--ik-radius);
    padding: clamp(1rem, 3vw, 1.5rem);
}

.ik-placeholder { border-style: dashed; }

/*
 * Same table look as .ik-resort-pick__table below (Hodnocení letoviska/pláže
 * panels use it too) — kept as its own class since the two live in
 * different containers, but the rules must stay in sync.
 */
.ik-facts-table {
    width: 100%;
    border-collapse: collapse;
    margin: 0;
}

.ik-facts-table th,
.ik-facts-table td {
    padding: 0.4rem 0.6rem;
    text-align: left;
    border-bottom: 1px solid var(--bs-border-color);
}

.ik-facts-table th {
    font-weight: 600;
    color: var(--ik-muted);
    width: 40%;
}

.ik-facts-table tr:last-child th,
.ik-facts-table tr:last-child td { border-bottom: 0; }

.ik-facts-table tr:nth-child(odd) { background: rgba(0, 0, 0, 0.025); }

/*
 * /vyber-letoviska.html: souhrnná tabulka pod filtrem. table-layout: fixed,
 * jinak auto layout ignoruje procenta u sloupců s krátkým obsahem (číslice)
 * a nechává volné místo. Krajní sloupce (Letovisko/Lokalita) souměrně širší
 * — oba nesou delší text — vnitřní dva (jen číslice) souměrně užší.
 * white-space: nowrap na Lokalitě, ať se jednoslovné názvy typu
 * "Středovýchodní Kréta" nelámou.
 */
.ik-resort-summary { table-layout: fixed; }
.ik-resort-summary th:nth-child(1),
.ik-resort-summary th:nth-child(4) { width: 32%; }
.ik-resort-summary th:nth-child(2),
.ik-resort-summary th:nth-child(3) { width: 18%; }
.ik-resort-summary td:nth-child(4) { white-space: nowrap; }

/*
 * /vyber-letoviska.html: one card per resort — map, facts table, CTA link,
 * held together as a single panel rather than loose siblings side by side.
 */
.ik-resort-pick {
    background: var(--ik-surface);
    border: 1px solid var(--bs-border-color);
    border-radius: var(--ik-radius);
    padding: clamp(1rem, 3vw, 1.5rem);
    margin-top: 1.5rem;
}

/* Title sits outside the row below, deliberately: that is what lets the
   table and the map both start flush with the row's own top edge instead
   of the map centering against the row's full height (title included). */
/*
 * .ik-resort-pick__title alone loses to theme-c.css's ".v-c h2" rule (higher
 * specificity, loads after site.css) — ".ik-resort-pick" doubles up the
 * class count to win outright regardless of load order.
 */
.ik-resort-pick .ik-resort-pick__title {
    margin-top: 0;
    padding-bottom: 0.5rem;
    border-bottom: 3px solid var(--ik-accent);
    /* Every other h2 on the site gets .v-c's left rule (theme-c.css) — this
       one is a title over a two-column row, where a second orange rule
       competing with the underline read as cluttered. Underline only. */
    border-left: 0;
    padding-left: 0;
}

.ik-resort-pick__row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 1.5rem;
}

/*
 * 2:1 grow ratio, table:map — the source thumbnail is 300px native, so
 * giving it an equal half stretched it soft and starved the table's own
 * column. max-width keeps it from ballooning further on wide screens until
 * a higher-resolution map replaces it.
 */
.ik-resort-pick__map {
    flex: 1 1 14rem;
    max-width: 20rem;
    width: 100%;
    height: auto;
    border-radius: calc(var(--ik-radius) - 2px);
    border: 1px solid var(--bs-border-color);
    background: #fff;
}

.ik-resort-pick__body {
    flex: 2 1 18rem;
    min-width: 0;
}

.ik-resort-pick__table {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 1rem;
}

.ik-resort-pick__table th,
.ik-resort-pick__table td {
    padding: 0.4rem 0.6rem;
    text-align: left;
    border-bottom: 1px solid var(--bs-border-color);
}

.ik-resort-pick__table th {
    font-weight: 600;
    color: var(--ik-muted);
    width: 40%;
}

.ik-resort-pick__table tr:last-child th,
.ik-resort-pick__table tr:last-child td { border-bottom: 0; }

.ik-resort-pick__table tr:nth-child(odd) { background: rgba(0, 0, 0, 0.025); }

.ik-stars { color: var(--ik-accent); font-size: 1rem; }

/*
 * _invia_hotels_table.twig. The hotel name is a link but reads as plain
 * text until hovered — a table full of standard blue underlines competed
 * with the rating badges below for attention.
 */
.ik-hotel-link { color: inherit; text-decoration: none; }
.ik-hotel-link:hover { color: var(--ik-accent); text-decoration: underline; }

/*
 * Guest rating, doubling as the link to the hotel's reviews on Invia — a
 * bare "4,5 / 5" in a table column got lost next to everything else on the
 * row, so it is a coloured pill instead. Thresholds follow the common
 * "good / average / poor" 5-point read (4,0+ / 3,0+ / below), the same
 * shape as Booking's 8/6-out-of-10 bands. Scale is the column header's job
 * ("Hodnocení na Invia (0–5)") and the tooltip's ("... 4,5 z 5 ..."), so the
 * pill itself only carries the number and the review count — repeating
 * "/ 5" on every row added width without adding information.
 */
.ik-rating-badge {
    display: inline-flex;
    align-items: baseline;
    gap: 0.15em;
    padding: 0.15em 0.6em;
    border-radius: 999px;
    /* At full body text size (the table's own default) the pill background
       read as louder than the rest of the row instead of a quiet detail
       next to the hotel name — 0.8125rem (.ik-eyebrow's size) went too far
       the other way. */
    font-size: 0.9rem;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}
.ik-rating-badge:hover { text-decoration: underline; }
.ik-rating-badge__total { font-weight: 400; font-size: 0.8em; opacity: 0.7; }

.ik-rating-badge--good { background: var(--bs-success-bg-subtle); color: var(--bs-success-text-emphasis); }
.ik-rating-badge--mid { background: var(--bs-warning-bg-subtle); color: var(--bs-warning-text-emphasis); }
.ik-rating-badge--poor { background: var(--bs-danger-bg-subtle); color: var(--bs-danger-text-emphasis); }

/* hotel_catalog.twig — klikací záhlaví sloupců, stejný GET-odkaz mechanismus jako filtry nad tabulkou. */
.ik-sort-link { color: inherit; text-decoration: none; }
.ik-sort-link:hover { text-decoration: underline; }
.ik-sort-link.is-active { color: var(--ik-accent); font-weight: 700; }

/* Quick-jump chips above the criteria form — a stable map of the island's
   four regions, not a shrinking facet count of the current filter. */
.ik-region-tiles {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 1.25rem;
}

.ik-region-tile {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: var(--ik-tap);
    padding: 0.4rem 0.9rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 999px;
    background: var(--ik-surface);
    color: inherit;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.9375rem;
}

.ik-region-tile:hover,
.ik-region-tile:focus-visible {
    border-color: var(--ik-accent);
}

.ik-region-tile span {
    color: var(--ik-muted);
    font-weight: 400;
}

.ik-region-tile.is-active {
    background: var(--ik-accent);
    border-color: var(--ik-accent);
    color: #fff;
}

.ik-region-tile.is-active span { color: inherit; opacity: 0.85; }

/*
 * /pocasi.html: the intro links to each region's forecast as solid tiles
 * (original site's a.box-weather/a.box-sea) rather than plain text links —
 * the classes come straight from the article content in the DB.
 */
.ik-prose a.box-weather,
.ik-prose a.box-sea {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--ik-tap);
    min-width: 8rem;
    padding: 0.5rem 1rem;
    margin: 0.25rem 0.4rem 0.25rem 0;
    border-radius: var(--ik-radius);
    color: #fff;
    text-decoration: none;
    text-align: center;
    font-weight: 600;
}

.ik-prose a.box-weather { background: var(--ik-accent); }
.ik-prose a.box-weather:hover,
.ik-prose a.box-weather:focus-visible { background: #cc7000; color: #fff; }

.ik-prose a.box-sea { background: #3295e6; }
.ik-prose a.box-sea:hover,
.ik-prose a.box-sea:focus-visible { background: #2778bb; color: #fff; }

/*
 * /pocasi.html: the monthly climate table (`table.ik-climate-table`, built by
 * ContentFormatter::renderWeatherClimate()) had no styling at all.
 * `display: block` + `overflow-x: auto` on the table itself scrolls it on
 * narrow screens without needing a wrapper <div>. A dedicated class, not the
 * old CMS's generic "Weather" — that name also landed on unrelated tables
 * imported straight from raw article content (e.g. the distances table in
 * the doprava article), which pulled in this styling, including the
 * warm-months row tint below, by accident.
 */
.ik-prose table.ik-climate-table {
    display: block;
    overflow-x: auto;
    /* fit-content, not 100%: display: block makes this box a plain block and
       wraps the rows in an anonymous table of their own, which is only as
       wide as its columns need — at 100% the box kept stretching past the
       last column, and the frame below then drew its right edge in empty
       space next to the rows. max-width still clamps it on narrow screens,
       where overflow-x scrolls the columns as before. */
    width: fit-content;
    max-width: 100%;
    border-collapse: collapse;
    margin: 1.5rem 0;
}

.ik-prose table.ik-climate-table th,
.ik-prose table.ik-climate-table td {
    padding: 0.5rem 0.9rem;
    text-align: center;
    border-bottom: 1px solid var(--bs-border-color);
    white-space: nowrap;
}

.ik-prose table.ik-climate-table td:first-child,
.ik-prose table.ik-climate-table th:first-child { text-align: left; }

/*
 * The frame further down closes this table at the bottom on its own, and on
 * this one the two lines don't merge: display: block takes the element out
 * of the table box, so its border sits outside the anonymous table holding
 * the rows instead of collapsing with the last row's own border — measured
 * live, that left the two 1.5px apart and read as one thick smudged line.
 * Dropping the last row's rule leaves the frame's edge alone down there.
 */
.ik-prose table.ik-climate-table tr:last-child th,
.ik-prose table.ik-climate-table tr:last-child td { border-bottom: 0; }

.ik-prose table.ik-climate-table tr:first-child th {
    font-weight: 600;
    color: var(--ik-muted);
    border-bottom: 2px solid var(--ik-accent);
}

/*
 * Bootstrap Icons (already loaded site-wide) glyphs, referenced directly by
 * codepoint — ::before can't insert a real <i class="bi-...">, only text
 * content. ContentFormatter::renderWeatherClimate() prints these classes
 * directly on the <th> elements it generates, so a class is used here
 * instead of the :nth-child() position hack the raw-HTML version needed.
 * Colours match the corresponding chart series below: accent for
 * temperature, the same blue as the sea chart and .box-sea, the same grey
 * as the rain chart.
 */
.ik-prose table.ik-climate-table th.ik-th-max::before,
.ik-prose table.ik-climate-table th.ik-th-avg::before,
.ik-prose table.ik-climate-table th.ik-th-sea::before,
.ik-prose table.ik-climate-table th.ik-th-rain::before {
    font-family: "bootstrap-icons" !important;
    font-style: normal;
    font-weight: 400 !important;
    margin-right: 0.35em;
}

.ik-prose table.ik-climate-table th.ik-th-max::before {
    content: "\f5ce"; /* thermometer-high — the "full" reading fits Max better than the half-full icon */
    color: var(--ik-accent);
}

.ik-prose table.ik-climate-table th.ik-th-avg::before {
    content: "\f5cd"; /* thermometer-half */
    color: var(--ik-accent);
}

.ik-prose table.ik-climate-table th.ik-th-sea::before {
    content: "\f617"; /* water */
    color: #3295e6;
}

.ik-prose table.ik-climate-table th.ik-th-rain::before {
    content: "\f2b6"; /* cloud-rain */
    color: #6c757d;
}

.ik-prose table.ik-climate-table tr:nth-child(even) { background: rgba(0, 0, 0, 0.025); }

/*
 * Rows 6–11 are Květen–Říjen (row 1 is the header) — the swimming/tourist
 * season, fixed by the table's own always-Leden-to-Prosinec row order. One
 * shade of tint for the whole span rather than a darker one for the
 * June–September peak (called out as unnecessary), but still alternating
 * between two strengths of it row-to-row — a flat block read as a single
 * merged panel instead of twelve separate months. The second, more specific
 * selector (three pseudo-classes vs. two) wins on the rows it also matches
 * regardless of source order, so which one is "even" doesn't need tracking.
 */
.ik-prose table.ik-climate-table tr:nth-child(n+6):nth-child(-n+11) {
    background: color-mix(in srgb, var(--ik-accent) 16%, transparent);
}

.ik-prose table.ik-climate-table tr:nth-child(n+6):nth-child(-n+11):nth-child(even) {
    background: color-mix(in srgb, var(--ik-accent) 7%, transparent);
}

/*
 * Raw tables straight from 2012 article content (e.g. the distances table
 * in the doprava article, the price/phone tables in taxi-pujcovny, the
 * beach-info tables in Rhodos's plaze) carry the old CMS's generic
 * `class="Weather"` plus inline `width`/`border` attributes, and lost all
 * styling when that class name was deliberately not reused above. This
 * gives them the same look as the climate table — scrollable instead of
 * overflowing on mobile, no bare HTML border — without touching
 * .ik-climate-table's own rules (kept separate by the :not()).
 *
 * display stays the table default (not display: block, tried first): a
 * <table> box always establishes its own BFC, so it already shrinks to fit
 * its content and avoids overlapping a {photo:right|...} float on its own
 * — no width rule needed for that. display: block would decouple the outer
 * box from the table layout algorithm that actually sizes the columns:
 * verified live, an explicit width/min-width on a display: block table
 * changed the outer box's measured width but every column still rendered
 * at its pre-existing size, squeezing Rhodos's beach-info tables into
 * unreadable one-word-per-line columns instead of using the extra space.
 * overflow-x is still here for tables genuinely wider than the viewport on
 * mobile, where a <table> box does respect it despite the default display.
 */
.ik-prose table:not(.ik-climate-table) {
    overflow-x: auto;
    max-width: 100%;
    border-collapse: collapse;
    margin: 1.5rem 0;
}

/*
 * Rhodos's per-beach info table (raw content: <table class="beach">, one
 * per beach in the "plaze" article, e.g. Lokalita/Vybavenost/Oblíbenost)
 * wraps its longer values into an unreadable one-word-per-line column with
 * no width rule at all — verified live with every style removed: a
 * key/value table with a few long cells simply has a narrow auto-layout
 * width by default, float or no float. The old site's own CSS gave this
 * exact class an explicit `width: 450px` (styles/tables.css `.beach`), but
 * that alone wasn't enough here: table-layout: auto (the default) doesn't
 * split the extra width between columns the way it looks like it should —
 * verified live, hand-widening the table just gave every extra pixel to
 * the label column, leaving the value column exactly as narrow as before.
 * table-layout: fixed sidesteps that entirely — column widths come only
 * from the first row's cells, so fixing the label column's width there is
 * enough to give the rest of the table's width to the value column, in
 * every row. clear keeps it from also sharing a line with the
 * {photo:right|...} that precedes each one — most of these still overlap
 * the photo's bottom edge right after a 2–3 line paragraph, and ducking in
 * beside it for only part of its height reads worse than always starting
 * on its own line.
 */
.ik-prose table.beach {
    clear: both;
    table-layout: fixed;
    width: 650px;
    max-width: 100%;
}

.ik-prose table.beach th {
    width: 160px;
}

.ik-prose table:not(.ik-climate-table) th,
.ik-prose table:not(.ik-climate-table) td {
    padding: 0.5rem 0.9rem;
    text-align: left;
    border-bottom: 1px solid var(--bs-border-color);
}

.ik-prose table:not(.ik-climate-table) tr:first-child th {
    font-weight: 600;
    color: var(--ik-muted);
    border-bottom: 2px solid var(--ik-accent);
}

/*
 * Label/amount tables (e.g. the taxi ceník in taxi-pujcovny) — right-align
 * the amount column so the figures line up on their decimal point instead
 * of ragging on the left under a left-aligned label column. Opt-in via
 * class, not a blanket last-child rule: the multi-column distances table
 * and the phone-number table share the same base selector above but
 * shouldn't get this (phone numbers aren't a magnitude to compare).
 */
.ik-prose table.ik-table-amounts td:last-child {
    text-align: right;
}

/*
 * The taxi ceník and the taxi contacts table (taxi-pujcovny) sit right next
 * to each other but hold different content, so left at their default
 * fit-content sizing (the table:not(.ik-climate-table) rule above sets no
 * width) they end up a few pixels apart — noticeable as a ragged edge since
 * they're stacked in the same narrow section. A shared fixed width, wide
 * enough for the longer table's own longest line (the contacts table's
 * phone-number rows), makes the pair line up without reintroducing the
 * import's old width="350", which was too narrow for either one and forced
 * wrapping on every screen size, not just small ones.
 */
.ik-prose table.ik-table-taxi {
    width: 490px;
    max-width: 100%;
}

.ik-prose table:not(.ik-climate-table) tr:nth-child(even) { background: rgba(0, 0, 0, 0.025); }

/*
 * A closed frame around the content tables — all four sides. Brings back the
 * outline the raw 2012 imports used to get from their own `border="1"`
 * attribute before it was styled away, now in the site's own border colour
 * instead of the browser's default ridge. The bottom edge comes from the
 * last row's own `border-bottom` collapsing into this one, so no extra rule
 * is needed for it. The panel tables (.ik-facts-table,
 * .ik-resort-pick__table) stay without a frame on purpose: they already sit
 * inside a bordered panel, and a second outline right inside the first
 * reads as a doubled border.
 *
 * :has(th) keeps the frame off the one purely presentational table left in
 * the content — the photo grid in the strava article, a layout table with
 * no header cell anywhere — where a box drawn around a gallery would read
 * as a mistake rather than as a table.
 */
.ik-prose table:has(th) {
    border: 1px solid var(--bs-border-color);
}

/*
 * Rhodos's "plaze" article (id 18, only site that has this) carries an
 * "Oblíbenost" row per beach. Tried reproducing the old CMS's star-rating
 * widget (a background-image sprite, Star00.png..Star10.png) first, but the
 * old site's own images are small (90×20) and visibly blurry once scaled up
 * to this site's larger type — not worth carrying forward just to match the
 * original pixel-for-pixel. Converted to plain text instead, reusing
 * .ik-score (below) — the same "N/10" treatment Kréta's own beach_list.twig
 * already gives `beach.rating.adminRating`, so Rhodos's imported score reads
 * exactly like a Kréta one instead of introducing a second rating style.
 */

/*
 * "Grafy" is an <h3> (a subsection of the table's own <h2>, not a new
 * top-level heading — see ContentFormatter::renderWeatherClimate()), but it
 * still gets the orange left rule theme-c.css gives every <h2>
 * (.v-c h2 { border-left: ...; padding-left: ...; }) so it still reads as a
 * section start rather than a plain paragraph-sized heading.
 */
.ik-prose h3.ik-weather-charts-heading {
    border-left: 4px solid var(--ik-accent);
    padding-left: 1rem;
}

/*
 * ContentFormatter::renderWeatherClimate() prints these — weather-charts-init.js
 * fills them with ECharts. Fixed height up front so the page doesn't jump
 * once the chart renders (no CLS).
 */
.ik-chart {
    width: 100%;
    height: clamp(260px, 48vw, 340px);
    margin: 1.5rem 0;
}

/*
 * hotel_catalog.twig dlaždice: "125 hotelů, 8545 recenzí" splývalo v jednu
 * šeď. Hotely dostávají barvu webu (totéž co aktivní stav dlaždice), recenze
 * zůstávají neutrálně šedé — .is-active výš má vyšší specificitu (dvě
 * třídy), takže na zvolené dlaždici obě zase splynou do bílé, schválně.
 */
.ik-region-tile:not(.is-active) span.ik-region-tile__hotels { color: var(--ik-accent); font-weight: 600; }

.ik-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    gap: 0.2rem;
}

.ik-list a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    min-height: var(--ik-tap);
    padding: 0.5rem 0.75rem;
    border-radius: var(--ik-radius);
    text-decoration: none;
    border: 1px solid transparent;
}

.ik-list a:hover,
.ik-list a:focus-visible {
    background: var(--ik-surface);
    border-color: var(--bs-border-color);
}

/*
 * Non-link rows (the intro list) share the link padding so the two columns
 * line up — and the same hover, so "Co lze na Krétě najít?" responds to the
 * pointer even though its rows are spans, not anchors. Full body text size,
 * same as the prototype's own .list-group-item — no shrink of its own.
 */
.ik-list .ik-line {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.75rem;
    border-radius: var(--ik-radius);
    transition: background-color 0.15s ease;
}

.ik-list .ik-line .ik-icon,
.ik-list .ik-line .bi { font-size: 1.05em; }

.ik-list li:hover > .ik-line {
    background: var(--ik-surface);
}

/* Editorial 0-10 score. Variant B turns this into a badge. */
.ik-score {
    color: var(--ik-muted);
    font-size: 0.9375rem;
    white-space: nowrap;
}

.ik-eyebrow {
    display: block;
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ik-muted);
    margin-bottom: 0.3rem;
}

.ik-meta {
    color: var(--ik-muted);
    font-size: 0.875rem;
    white-space: nowrap;
}

/*
 * The intro article's own photo, floated beside the highlight list — same
 * placement the {photo:right|...} shortcode gives it in the source text.
 * A bordered box around image + caption, like the prototype's card, rather
 * than a bare thumbnail floating loose in the text.
 */
.ik-lead-photo {
    display: block;
    max-width: 13rem;
    margin: 0 0 1rem 1rem;
    text-decoration: none;
    color: inherit;
    border: 1px solid var(--bs-border-color);
    border-radius: var(--ik-radius);
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/*
 * clear: a run of several {photo:right|...} shortcodes (plaze's "10
 * Nejlepších pláží" and other list-style articles) must stack strictly
 * below one another. Without it, a photo that starts while the previous one
 * is still floating doesn't queue below it — CSS places it as far right as
 * space allows, which is immediately to that float's *left* — so it reads
 * as photos drifting left instead of staying flush right. This is a
 * defensive backstop: the --compact size below is chosen to normally clear
 * on its own (see that rule's comment), so this only bites for an unusually
 * short paragraph.
 */
.ik-lead-photo--left { float: left; clear: left; margin: 0 1.25rem 1rem 0; }
.ik-lead-photo--right { float: right; clear: right; margin: 0 0 1rem 1.25rem; }

.ik-lead-photo img {
    display: block;
    width: 100%;
    height: auto;
}

/*
 * Smaller, fixed-crop variant for {photo:...} shortcodes repeated through an
 * article's body (ContentFormatter::renderPhoto()) — plaze's "10 Nejlepších
 * pláží" is the worst case, a dozen in a row. The base 13rem size above is
 * fine for a single hero photo (home page intro, resort/beach cover, never
 * repeated on a page) but is too wide once several appear in sequence.
 * object-fit: cover gives every one of them the exact same box regardless of
 * the source photo's own aspect ratio (800×220 through 533×800 among these
 * ten) — both are the "same size, right-aligned" look. Sizing doesn't affect
 * correctness — clear: above unconditionally queues the next float below the
 * previous one — so this is a pure legibility call: 8rem read too small on a
 * modern screen (was 6rem), a short 2-line paragraph just leaves a bit more
 * blank space above the next heading.
 */
.ik-lead-photo--compact {
    max-width: 8rem;
}

.ik-lead-photo--compact img {
    aspect-ratio: 4 / 3;
    object-fit: cover;
}

/* Clears the floated photo so the next heading doesn't run up against it. */
.ik-clear { clear: both; }

@media (max-width: 420px) {
    .ik-lead-photo { float: none; max-width: 100%; margin: 0 0 1rem; }
}

/* Thumbnail grid for beach/resort/tourist-object photo galleries. */
.ik-gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
    gap: 0.5rem;
}

.ik-gallery__item {
    display: block;
    aspect-ratio: 4 / 3;
    border-radius: var(--ik-radius);
    overflow: hidden;
}

.ik-gallery__item img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.2s ease;
}

.ik-gallery__item:hover img { transform: scale(1.05); }

/*
 * Předpověď počasí.
 *
 * Dvě rozvržení, každé ve své media query: do 992 px karta, od 992 px tabulka
 * o pěti sloupcích. Nedělí se to na „základ + výjimky“, protože společného
 * nemají skoro nic — karta staví údaje do mřížky 3×3, tabulka do řádku — a
 * řetěz resetů byl delší než obojí zvlášť. Pět sloupců vedle sebe by na užší
 * obrazovce vynutilo vodorovné posouvání, což je přesně to, co fáze 3 zakázala.
 */
/*
 * Barvy oblohy na jednom místě. Nese je ikona jevu i ciferník hodin a musí
 * si odpovídat — jinak svítí slunce zlatě a ciferník vedle něj oranžově.
 */
.ik-weather {
    --ik-sky-day: #f0ad00;
    --ik-sky-night: #5b7fb5;
    --ik-sky-cloud: #7b93ab;

    width: 100%;
    border-collapse: collapse;
    margin-top: 0.75rem;
}


.ik-weather__gust { color: var(--ik-muted); font-size: 0.875rem; }
.ik-weather__day { margin-top: 1.75rem; }
.ik-weather__age { margin-bottom: 0; }

/*
 * .ik-meta nese white-space: nowrap kvůli krátkým jednořádkovým údajům
 * („Východ 06:33 · Západ 20:26“). Tyhle dva odstavce jsou ale celé věty:
 * bez zalomení přetečou z obrazovky ven a celá stránka dostane vodorovný
 * posuvník (naměřeno 498 px obsahu na displeji širokém 420 px).
 */
.ik-weather__age,
.ik-weather__source { white-space: normal; }

/* ------------------------------------------------------- ikony v předpovědi */

/*
 * Ikony jsou záměrně velké — na starém webu nesly půlku sdělení a v drobném
 * provedení by byly jen ozdoba. Velikosti proto rostou s šířkou okna přes
 * clamp(); konkrétní hodnoty si nastavuje každé rozvržení samo (viz obě
 * media query níž), protože v tabulce jich je pět v řadě a na kartě čtyři
 * s různou důležitostí.
 */
.ik-weather__sky-name { line-height: 1.25; }

.ik-weather__wind-icons,
.ik-weather__time {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

/* Ikony si drží velikost, mačká se text — ne naopak. */
.ik-weather__wind-icons { flex: none; }

/*
 * flex-wrap je pojistka: kdyby se ciferník s časem do sloupce nevešly,
 * zalomí se pod sebe místo aby přetekly do sousedního. Přesně tohle sloupec
 * Čas dělal, dokud měl 13 % — vypisoval „18:0029 °C“.
 */
.ik-weather__time { flex-wrap: wrap; }

/*
 * Barvy ikon oblohy.
 *
 * Slunce zlatožlutě, ne oranžově: oranžová je barva --ik-secondary, tedy
 * značky webu, a slunce s ní vycházelo přepálené v každém motivu. Zlatá je
 * navíc to, co člověk slunci sám přisoudí. Mraky, déšť a sníh zůstávají
 * chladné — dřív svítily oranžově stejně jako slunce, takže z barvy nešlo
 * poznat, jestli je jasno, nebo leje.
 *
 * V noci je celá sada modrá, stejně jako ciferník hodin, aby den od noci šel
 * poznat na pohled, ne až po přečtení času.
 */
.ik-weather__phenomenon {
    font-size: var(--ik-ico-sky, 2rem);
    line-height: 1;
    color: var(--ik-sky-cloud);
    flex: none;
}

.ik-weather__phenomenon.bi-sun-fill,
.ik-weather__phenomenon.bi-cloud-sun-fill { color: var(--ik-sky-day); }

.ik-weather__phenomenon.is-night { color: var(--ik-sky-night); }

/*
 * Optická korekce měsíce. Kresby jsou stejně velké — změřeno na canvasu, tah
 * slunce má 200×160, měsíce 188×160 — jenže slunce je kotouček s tenkými
 * paprsky, kdežto měsíc plný srpek s hvězdami. Při stejné velikosti proto
 * měsíc vedle slunce působí větší. Osm procent dolů to srovná na pohled.
 */
.ik-weather__phenomenon.bi-moon-stars-fill {
    font-size: calc(var(--ik-ico-sky, 2rem) * 0.92);
}

.ik-weather__arrow { font-size: var(--ik-ico-wind, 2rem); color: var(--ik-muted); }
.ik-weather__dir { color: var(--ik-muted); }
.ik-weather__chance { display: block; color: var(--ik-muted); font-size: 0.875rem; }

/* Číslo tmavé jako hlavní údaj, jednotka šedě jako na meteo.gr. */
.ik-weather__unit { color: var(--ik-muted); margin-left: 0.1em; }

/*
 * Záložní hodnoty ve var() nejsou zdobení. Když proměnná chybí, je celá
 * deklarace neplatná a SVG bez width/height se vykreslí ve své vlastní
 * velikosti — tedy přes půl obrazovky. Jednou se to už stalo.
 */
.ik-weather__clock {
    width: var(--ik-ico-clock, 2rem);
    height: var(--ik-ico-clock, 2rem);
    flex: none;
    color: var(--ik-sky-day);
}

/* V noci modrý jako měsíc — den od noci jde poznat i bez čtení času. */
.ik-weather__clock.is-night { color: var(--ik-sky-night); }

.ik-weather__drops { white-space: nowrap; font-size: 0.75rem; color: #3d9be9; }
.ik-weather__drops .is-empty { opacity: 0.25; }

/* Barvy stupňů přebírají odstíny meteo.gr, aby to čtenář poznal ze zvyku. */
.ik-weather__mosquito { font-size: clamp(0.9rem, 2.2vw, 1.25rem); line-height: 1; }
.ik-weather__mosquito--1 { color: #a7d946; }
.ik-weather__mosquito--2 { color: #f2d02a; }
.ik-weather__mosquito--3 { color: #e69724; }
.ik-weather__mosquito--4 { color: #c60300; }

/* <use>d Font Awesome sprite (weather.twig) — sized/coloured like a Bootstrap
   Icons glyph (1em box, fill from the span's own color) so it drops into
   the same spot the bi-bug-fill icon used to sit in. */
.ik-mosquito-icon { width: 1em; height: 1em; fill: currentColor; vertical-align: -0.125em; }

.ik-weather__maxtemp { font-size: 0.5rem; vertical-align: super; color: #c60300; }

/* Pocitová teplota — teplá/studená barva podle směru, stejná paleta jako komáři a kapky vlhkosti. */
.ik-weather__felt-temp { font-size: clamp(0.9rem, 2.2vw, 1.25rem); line-height: 1; margin-left: 0.25rem; vertical-align: middle; }
.ik-weather__felt-temp--hotter { color: #e63024; }
.ik-weather__felt-temp--colder { color: #3d9be9; }

.ik-weather__alert { border-left: 4px solid #c60300; }

/* Popisek nese celou větu, takže potřebuje víc místa než výchozí Bootstrap. */
.tooltip-inner {
    max-width: 18rem;
    font-size: 0.9375rem;
    line-height: 1.4;
    padding: 0.5rem 0.75rem;
    text-align: left;
}

/*
 * Větrník: rychlost otáčení nese sílu větru, stejně jako u meteo.gr. Dobu
 * otáčky posílá šablona přes --ik-spin, protože vychází z naměřeného stupně.
 */
.ik-weather__windmill {
    width: var(--ik-ico-wind, 2rem);
    height: var(--ik-ico-wind, 2rem);
    color: var(--ik-muted);
    flex: none;
}

/* Barva podle síly větru, jako u meteo.gr — slabý vítr modře, silnější přes zelenou a žlutou až po červenou. */
.ik-weather__windmill--blue { color: #2f8fd1; }
.ik-weather__windmill--green { color: #2e9e44; }
.ik-weather__windmill--yellow { color: #c99400; }
.ik-weather__windmill--orange { color: #e0791f; }
.ik-weather__windmill--red { color: #d1352b; }

.ik-weather__blades {
    /* Souřadnice jsou z viewBox, ne z ohraničení lopatek — jinak by se vrtule
       netočila kolem náboje, ale kolem rohu svého obalu. */
    transform-box: view-box;
    transform-origin: 12px 10px;
    animation: ik-windmill var(--ik-spin, 5s) linear infinite;
}

@keyframes ik-windmill {
    to { transform: rotate(360deg); }
}

/*
 * Na stránce je až 45 točících se vrtulí. Komu systém animace vypíná, tomu
 * musí zůstat stát — jinak je to na čtení nepoužitelné.
 */
@media (prefers-reduced-motion: reduce) {
    .ik-weather__blades { animation: none; }
}

/*
 * ---------------------------------------------------- karta (do 992 px)
 *
 * Jeden tříhodinový slot je uzavřený blok:
 *
 *     ┌──────────────────────────────────┐
 *     │ 🕐 18:00       29 °C         ☀️  │  hlavička na šedém pruhu
 *     ├──────────────────────────────────┤
 *     │ Jasno 🦟             vlhkost 48 %│
 *     │ ↙ 🌀 Slabý vítr SZ · 16 km/h     │
 *     └──────────────────────────────────┘
 *
 * Hlavička nese tři údaje, na které se člověk dívá první (kdy, kolik stupňů,
 * jak vypadá obloha), zbytek jsou podrobnosti pod ní. Rámeček sám o sobě
 * nestačil — karty splývaly a jediný předěl, který šel vidět, byl přechod
 * mezi denním a nočním slotem.
 *
 * Popisky sloupců se neopakují; nese je jednotka, ikona nebo slovní popis
 * síly větru. Jediná výjimka je vlhkost/tlak: holé „48 %“ nic neřekne.
 */
@media (max-width: 991.98px) {
    .ik-weather { display: block; }
    .ik-weather thead { display: none; }

    .ik-weather tbody {
        display: flex;
        flex-direction: column;
        gap: 0.6rem;
    }

    /*
     * Obloha je kotva, na kterou oko skočí první, proto je z nich největší.
     * Zbylé tři jsou detaily u textu a zůstávají drobné — bez toho by se
     * hlavička na 320 px nevešla na jeden řádek.
     */
    .ik-weather {
        --ik-ico-sky: clamp(1.5rem, 5vw, 2rem);
        --ik-ico-wind: 1.25rem;
        --ik-ico-clock: 1.15rem;
    }

    .ik-weather tr {
        display: grid;
        grid-template-columns: 1fr auto 1fr;
        grid-template-areas:
            "time temp sky"
            "phen phen hum"
            "wind wind wind";
        align-items: center;
        column-gap: 0;
        row-gap: 0.3rem;
        padding-bottom: 0.6rem;
        border: 1px solid var(--bs-border-color);
        border-radius: var(--ik-radius);
        /* aby šedý pruh hlavičky respektoval zaoblené rohy */
        overflow: hidden;
    }

    .ik-weather td {
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        gap: 0.15rem 0.4rem;
        min-width: 0;
    }

    /*
     * Hlavička. Všechny tři buňky se roztahují přes celou svoji stopu a mezi
     * sloupci není mezera, takže jejich podklady navazují do jednoho pruhu —
     * samostatný prvek na hlavičku v tabulce není. Zarovnání nese obsah
     * uvnitř buňky, ne poloha buňky: vlevo, na střed, vpravo.
     *
     * Podklad je neutrální ztmavení, ne pevná barva. Na denní kartě zešedne
     * bílou, na noční ztmaví modrý nádech a v jiném motivu bude fungovat taky.
     */
    .ik-weather td:nth-child(1),
    .ik-weather td:nth-child(2),
    .ik-weather__phenomenon {
        align-self: stretch;
        padding: 0.4rem 0.6rem;
        background: color-mix(in srgb, #000 5%, transparent);
    }

    /*
     * Čas zůstává v normálním řezu. Zvýrazněná je teplota v odznaku a dvě
     * tučné věci vedle sebe by se přebíjely — navíc tučné „18:00“ je o 4 px
     * širší a na 320 px se pak i s ciferníkem nevejde na řádek.
     */
    .ik-weather td:nth-child(1) { grid-area: time; }
    .ik-weather__time { gap: 0.3rem; }

    /*
     * Teplota je to, na co se člověk dívá první, ale v řadě tří údajů na
     * jednom pruhu se ztrácela. Odznak ji vyzvedne, aniž by musela být větší
     * nebo barevná. Užší odsazení buňky proto, že si odznak nese vlastní —
     * bez toho by prostřední sloupec ukrojil místo časům po stranách.
     */
    .ik-weather td:nth-child(2) {
        grid-area: temp;
        justify-content: center;
        padding-inline: 0.3rem;
    }

    .ik-weather__temp {
        padding: 0.05rem 0.55rem;
        border-radius: 999px;
        border: 1px solid var(--bs-border-color);
        background: var(--bs-body-bg);
        font-weight: 600;
        white-space: nowrap;
    }

    .ik-weather__phenomenon {
        grid-area: sky;
        display: flex;
        align-items: center;
        justify-content: flex-end;
    }

    /*
     * Buňka Počasí se v kartě rozpadá na dvě místa — ikona do hlavičky,
     * název jevu mezi podrobnosti. `display: contents` na buňce i na obalu
     * proto, aby mřížku karty viděl přímo jejich obsah.
     */
    .ik-weather td:nth-child(5),
    .ik-weather td:nth-child(5) > .ik-weather__sky { display: contents; }

    .ik-weather__sky-text { grid-area: phen; }
    .ik-weather td:nth-child(4) { grid-area: wind; }

    /* nowrap: „48“ a „%“ jsou jeden údaj, nesmí se rozejít na dva řádky. */
    .ik-weather td:nth-child(3) {
        grid-area: hum;
        justify-content: flex-end;
        white-space: nowrap;
    }

    /* Podrobnosti lícují s hlavičkou. */
    .ik-weather__sky-text,
    .ik-weather td:nth-child(3),
    .ik-weather td:nth-child(4) { padding-inline: 0.6rem; }

    .ik-weather__stack,
    .ik-weather__sky-text,
    .ik-weather__wind-text,
    .ik-weather__wind {
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        gap: 0.35rem;
    }

    /* Ikony větru před text: co je vidět dřív, patří na začátek řádku. */
    .ik-weather__wind-icons { order: -1; gap: 0.3rem; }

    .ik-weather__wind-text { row-gap: 0; }

    /*
     * Dva údaje na jednom řádku potřebují oddělovač; ve sloupci pod sebou ne.
     * Tečka visí na konci prvního údaje, ne na začátku druhého — po zalomení
     * na úzké obrazovce pak nezačíná řádek tečkou.
     */
    .ik-weather__wind-text > span:first-child::after {
        content: " ·";
        color: var(--ik-muted);
    }

    .ik-weather__wind-text > span:only-child::after { content: none; }

    /*
     * Kapky, ne slovo „vlhkost“. Ušetří ~10 px a o ty jde: název jevu vedle
     * může být „Snížená viditelnost“ a oba se dělí o jeden řádek. Slovo
     * zůstává ve značkování jako skrytý text pro čtečku, která z kapek
     * (aria-hidden) nic nemá.
     */
    .ik-weather__drops { font-size: 0.6875rem; }

    /*
     * Číslo a kapky drží u sebe. Od ~380 px se vejdou na jeden řádek, pod tím
     * kapky spadnou pod číslo — dál je zmenšovat nemá smysl, na 360 px chybí
     * ~4 px a čitelnost stojí víc než ten jeden řádek.
     */
    .ik-weather__stack { gap: 0.3rem; }

    /*
     * Den teple, noc studeně — ne aby to bylo pestré, ale aby šlo poznat na
     * pohled, kde končí odpoledne a začíná noc. Osm slotů denně je moc na to,
     * aby se musely číst po jednom, a ikona oblohy je na to sama malá.
     *
     * Odstíny jsou zesvětlené barvy těch ikon (zlatá slunce, modrá měsíce),
     * ať to drží pohromadě. Přes color-mix, aby seděly na podklad kteréhokoli
     * motivu. V tabulce se nepoužívají — tam si řádky střídají barvu obden.
     */
    .ik-weather tr { background: color-mix(in srgb, #f0ad00 4%, transparent); }

    .ik-weather tr:has(.ik-weather__phenomenon.is-night) {
        background: color-mix(in srgb, #5b7fb5 4%, transparent);
    }
}

/*
 * ------------------------------------------------- tabulka (od 992 px)
 *
 * Práh je 992 px, ne 768.
 *
 * Na 768 px je tabulka široká jen ~640 px a stránka tam zároveň přepíná na
 * písmo 18 px. Pět sloupců se do toho nevejde: naměřená potřeba obsahu je
 * 641 px u mořských lokalit (sloupec Tlak nese „1013 mbar“, tedy víc než
 * „48 %“ u měst). Právě tam se dřív text přepisoval přes sousední sloupec.
 * Do 992 px proto zůstává karta.
 */
@media (min-width: 992px) {
    /*
     * Jedna velikost pro všechny ikony v řádku — slunce/měsíc, směr větru,
     * vrtule i hodiny. Dřív měl vítr a čas vlastní, menší proměnné, takže
     * působily jako druhořadý údaj, i když nesou stejně důležitou informaci.
     * Na kartě to je naopak (viz začátek bloku): tam jsou ikony jen dvě.
     */
    .ik-weather {
        --ik-ico-sky: clamp(1.9rem, 5vw, 2.9rem);
        --ik-ico-wind: var(--ik-ico-sky);
        --ik-ico-clock: var(--ik-ico-sky);
    }

    /*
     * table-layout: fixed s pevnými šířkami — bez něj si prohlížeč nechá
     * sloupec Vítr (nejširší obsah, dvě velké ikony) narůst na úkor volného
     * místa mezi ním a Teplotou/Vlhkostí, takže záhlaví „Vítr“ sedí úplně
     * vlevo a obsah (zarovnaný doprava k ikonám) je od něj kus pryč. Pevné
     * procentní šířky drží sloupce u sebe podle skutečné potřeby.
     */
    /*
     * Mřížka tabulky drží jednu tloušťku i barvu — obrys, předěly sloupců
     * i linka pod záhlavím berou tuhle proměnnou, aby se nemohly rozejít.
     */
    .ik-weather {
        --ik-weather-rule: color-mix(in srgb, var(--bs-border-color) 80%, transparent);

        table-layout: fixed;
        border: 1px solid var(--ik-weather-rule);
        border-radius: var(--ik-radius);

        /*
         * Zaoblení jako u ostatních karet na webu. Musí k němu být
         * `border-collapse: separate`, protože při `collapse` se rádius na
         * tabulku nepropíše — podklad záhlaví by rohy zase zastřihl do
         * pravého úhlu. Zdvojené linky tím nevzniknou: rámeček nese vždycky
         * jen jedna strana z dvojice (`td + td` má border-left, ne oba).
         */
        border-collapse: separate;
        border-spacing: 0;
        overflow: hidden;
    }
    .ik-weather td, .ik-weather th { padding: 0.5rem 0.75rem; text-align: center; }
    /*
     * Záhlaví dne na tmavším pruhu — stejné neutrální ztmavení jako hlavička
     * karty na mobilu, jen o kus silnější, aby se nepletlo s pruhovanými
     * řádky pod ním (ty mají --ik-surface, tedy sotva 3 % šedi). Sedm dní
     * pod sebou tak dostane rytmus a je vidět, kde který začíná.
     */
    .ik-weather th {
        font-size: 0.875rem;
        color: var(--ik-muted);
        background: color-mix(in srgb, #000 7%, transparent);
        border-bottom: 1px solid var(--ik-weather-rule);
    }
    .ik-weather tbody tr:nth-child(odd) { background: var(--ik-surface); }

    /*
     * NÁHLED: svislé předěly mezi sloupci. Zatím jen na ukázku, jak to
     * působí — když se to neujme, jde ven jedno pravidlo.
     *
     * Linka je schválně slabší než rámečky jinde na stránce: má sloupce
     * rozdělit, ne nakreslit mříž. Proto ~55 % krytí barvy okrajů.
     */
    .ik-weather td + td,
    .ik-weather th + th {
        border-left: 1px solid var(--ik-weather-rule);
    }

    /*
     * Procenta odpovídají naměřené potřebě obsahu, ne odhadu. Sloupec užší,
     * než co se v něm nedá zalomit, s `table-layout: fixed` nepřeteče do
     * prázdna, ale do sousedního sloupce — proto se Čas při 13 % vypisoval
     * jako „18:0029 °C“. Ověřuje se to skriptem v poznámkách k této změně:
     * na žádné šířce nesmí být td.scrollWidth > td.clientWidth.
     */
    .ik-weather th:nth-child(1), .ik-weather td:nth-child(1) { width: 18%; text-align: left; }
    .ik-weather th:nth-child(2), .ik-weather td:nth-child(2) { width: 12%; }
    .ik-weather th:nth-child(3), .ik-weather td:nth-child(3) { width: 14%; }
    .ik-weather th:nth-child(4), .ik-weather td:nth-child(4) { width: 31%; }

    /* Vpravo víc místa, aby ikona počasí nebyla nalepená na hranu tabulky. */
    .ik-weather th:nth-child(5), .ik-weather td:nth-child(5) { width: 25%; padding-right: 1.25rem; }

    /* Kapky pod číslem, ne vedle — číslo je hlavní údaj. */
    .ik-weather__stack {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 0.2rem;
    }

    /*
     * Počasí a Vítr: text vlevo, ikony ve sloupci `auto` vpravo. Ten je na
     * všech řádcích stejně široký (vždycky stejný počet stejně velkých ikon),
     * takže ikony drží svislou linku bez ohledu na délku textu („Vánek“ vs.
     * „Dosti čerstvý vítr“). Vítr měl dřív dvě poloviny 1fr 1fr, což mezi textem a
     * ikonami nechávalo díru a sloupec zbytečně roztahovalo.
     */
    .ik-weather__sky,
    .ik-weather__wind {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: center;
        gap: 0.6rem;
    }

    .ik-weather__sky-text,
    .ik-weather__wind-text {
        display: flex;
        flex-direction: column;
        align-items: center;
        text-align: center;
        gap: 0.15rem;
    }

    .ik-weather__wind-icons { justify-content: center; gap: 0.35rem; }
}

.ik-dictionary { display: grid; gap: 0.75rem; }

@media (min-width: 768px) {
    .ik-dictionary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.ik-word {
    border-bottom: 1px solid var(--bs-border-color);
    padding-bottom: 0.55rem;
}

.ik-word b { font-weight: 600; }
.ik-word span { color: var(--ik-muted); }

.ik-foot {
    border-top: 1px solid var(--bs-border-color);
    margin-top: 2.5rem;
    padding: 1.75rem var(--ik-gap);
    color: var(--ik-muted);
    font-size: 0.9375rem;
}

.ik-foot p { margin: 0; }

/* ------------------------------------------------------------------ a11y */

.ik-skip {
    position: absolute;
    left: -9999px;
    z-index: 1080;
    padding: 0.75rem 1.25rem;
    background: var(--bs-body-bg);
    color: var(--bs-body-color);
    border: 1px solid var(--bs-border-color);
    border-radius: var(--ik-radius);
}

.ik-skip:focus { left: 1rem; top: 1rem; }

:focus-visible {
    outline: 3px solid var(--ik-accent);
    outline-offset: 2px;
}

.ik-muted { color: var(--ik-muted); }

/* Development only, removed with the losing variants. */
.ik-themebar {
    background: #1b1b1b;
    color: #eee;
    font-size: 0.875rem;
    padding: 0.5rem clamp(1rem, 4vw, 2rem);
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1rem;
    align-items: baseline;
}

.ik-themebar a { color: #8ecbff; }
.ik-themebar b { color: #fff; }
.ik-themebar .is-on { color: #ffd479; text-decoration: none; }

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/*
 * Zájezdy z feedu Invie (F7).
 *
 * Nabídka je karta se třemi sloupci — fotka, popis, cena a tlačítko. Pod
 * 720 px se to skládá pod sebe; mřížku dělá grid, ne breakpointy Bootstrapu,
 * protože poměr sloupců je tu daný obsahem, ne dvanáctinami.
 */
.ik-tours {
    display: grid;
    gap: 1rem;
    margin-top: 1.25rem;
}

.ik-tour {
    display: grid;
    grid-template-columns: minmax(0, 15rem) minmax(0, 1fr) minmax(0, 13.5rem);
    gap: 0 1.25rem;
    background: var(--ik-surface);
    border: 1px solid var(--bs-border-color);
    border-radius: var(--ik-radius);
    overflow: hidden;
}

.ik-tour__photo {
    position: relative;
    display: block;
    align-self: stretch;
}

.ik-tour__photo img {
    width: 100%;
    height: 100%;
    /* Fotky z feedu mají poměr 450×300, ale spoléhat se na to nejde. */
    object-fit: cover;
    display: block;
}

.ik-tour__discount {
    position: absolute;
    inset: auto auto 0.5rem 0.5rem;
    background: #c1121f;
    color: #fff;
    font-weight: 700;
    font-size: 0.85rem;
    padding: 0.15rem 0.5rem;
    border-radius: 0.35rem;
}

.ik-tour__body { padding: 1rem 0; min-width: 0; }

.ik-tour__name {
    font-size: 1.1rem;
    margin: 0 0 0.15rem;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.4rem;
}

.ik-tour__name a { text-decoration: none; }
.ik-tour__stars { color: #f0a500; font-size: 0.8em; white-space: nowrap; }

.ik-tour__where {
    color: var(--ik-muted);
    font-size: 0.9rem;
    margin: 0 0 0.6rem;
}

.ik-tour__facts {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    gap: 0.3rem;
    font-size: 0.9rem;
}

.ik-tour__facts .bi { color: var(--ik-accent); margin-right: 0.35rem; }

.ik-tour__buy {
    padding: 1rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: stretch;
    gap: 0.5rem;
    text-align: center;
    background: rgb(0 0 0 / 3%);
}

.ik-tour__price { margin: 0; line-height: 1.2; }
.ik-tour__price strong { font-size: 1.35rem; display: block; }
.ik-tour__price small { color: var(--ik-muted); }

.ik-tour__tag {
    margin: 0;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.ik-tour__tag--lm { color: #c1121f; }

/* Dlouhá věta pod výpisem. Schválně nemá .ik-meta — ta je na krátké
   jednořádkové údaje a nese white-space: nowrap, takže by odstavec přetekl
   z obrazovky ven. */
.ik-tours__note {
    margin-top: 1rem;
    color: var(--ik-muted);
    font-size: 0.875rem;
}

/* Tlačítko. Vlastní, aby neneslo celou sadu barev Bootstrapu kvůli jednomu
   odstínu — barva webu je proměnná a musí se přenést i sem. */
.ik-btn {
    display: inline-block;
    background: var(--ik-accent);
    color: #fff;
    font-weight: 600;
    text-decoration: none;
    text-align: center;
    border: 0;
    border-radius: var(--ik-radius);
    padding: 0.5rem 1rem;
    cursor: pointer;
}

.ik-btn:hover,
.ik-btn:focus-visible { filter: brightness(0.92); color: #fff; }

/* Řazení výpisu — obyčejné odkazy, ne formulář. */
.ik-tour-sort {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 0.9rem;
    align-items: baseline;
    margin: 0.35rem 0 0;
    font-size: 0.9rem;
}

.ik-tour-sort > span { color: var(--ik-muted); }
.ik-tour-sort strong { color: var(--ik-accent); }

/*
 * Panel „Vlastní kritéria výběru do této destinace“.
 *
 * Stojí v hlavním sloupci nad výpisem, na stejném místě jako na staré verzi.
 * Mřížka se sama přelije z šesti polí do dvou i do jednoho podle šířky —
 * `auto-fit` s minimem místo breakpointů, protože počet polí je daný
 * konfigurací a může se změnit.
 */
.ik-invia-search {
    background: var(--ik-surface);
    border: 1px solid var(--bs-border-color);
    border-radius: var(--ik-radius);
    padding: clamp(0.9rem, 3vw, 1.25rem);
    margin-top: 1.25rem;
}

.ik-invia-search__title {
    font-size: 1rem;
    margin: 0 0 0.85rem;
}

.ik-invia-search__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 0.7rem 1rem;
    align-items: end;
}

.ik-invia-search label {
    display: block;
    font-size: 0.8rem;
    font-weight: 600;
    margin-bottom: 0.2rem;
}

.ik-invia-search select {
    width: 100%;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.35rem;
    padding: 0.4rem 0.5rem;
    background: var(--bs-body-bg, #fff);
    color: inherit;
}

.ik-invia-search__actions .ik-btn { width: 100%; }

.ik-invia-search__note {
    font-size: 0.8rem;
    color: var(--ik-muted);
    margin: 0.85rem 0 0;
}

/*
 * Choices.js (vendored, MIT — choices.min.js/css) turns the plain
 * <select multiple> filters on /vyber-letoviska.html into closed comboboxes
 * that open a checkbox list. Only resort-picker-init.js reaches for these
 * classes; every rule here is cosmetic on top of the library's own CSS, not
 * a replacement for it.
 */
.ik-resort-filter.choices { margin-bottom: 0; }

.ik-resort-filter .choices__inner {
    min-height: var(--ik-tap);
    border: 1px solid var(--bs-border-color);
    border-radius: 0.35rem;
    background: var(--bs-body-bg, #fff);
    padding: 0.3rem 0.5rem;
}

.ik-resort-filter.is-focused .choices__inner,
.ik-resort-filter.is-open .choices__inner { border-color: var(--ik-accent); }

.ik-resort-filter .choices__list--multiple .choices__item {
    background: var(--ik-accent);
    border-color: var(--ik-accent);
}

/* The dropdown list item itself gets a checkbox drawn in front of it —
   Choices.js has no checkbox mode of its own, so this is CSS only: a plain
   box that fills in and gets a ✓ once the library adds .is-selected. */
.ik-resort-filter .choices__item--selectable {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.ik-resort-filter .choices__item--selectable::before {
    content: "";
    flex-shrink: 0;
    width: 1.05em;
    height: 1.05em;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.25em;
    background: var(--bs-body-bg, #fff);
}

.ik-resort-filter .choices__item--selectable.is-selected::before {
    background: var(--ik-accent);
    border-color: var(--ik-accent);
    /* A ✓ drawn in CSS, not an image — one colour, no extra asset. */
    background-image: linear-gradient(45deg, transparent 40%, #fff 40%, #fff 55%, transparent 55%),
        linear-gradient(-45deg, transparent 55%, #fff 55%, #fff 70%, transparent 70%);
}

/*
 * One reset for all four fields, above the submit button rather than below
 * it — the grid aligns every column to its own bottom edge
 * (.ik-invia-search__grid's align-items: end), so a line above the button
 * mirrors each select's own <label> above it, and the buttons/comboboxes
 * all land on the same bottom line. Below the button, the reset link's own
 * height would have pushed the button up off that line instead.
 */
.ik-resort-filter__reset {
    display: block;
    margin-bottom: 0.2rem;
    font-size: 0.8rem;
    color: var(--ik-muted);
}

.ik-resort-filter__reset:hover,
.ik-resort-filter__reset:focus-visible { color: var(--ik-accent); }

@media (max-width: 720px) {
    .ik-tour {
        grid-template-columns: 1fr;
        gap: 0;
    }

    .ik-tour__photo img { height: 11rem; }
    .ik-tour__body { padding: 1rem; }

    .ik-tour__buy {
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: space-between;
        align-items: center;
        text-align: left;
    }

    .ik-tour__price strong { display: inline; }
    .ik-tour__buy .ik-btn { flex: 1 1 100%; }
}

/* Kolik dalších termínů hotel nabízí — doplněk k datu, ne samostatný fakt. */
.ik-tour__terms {
    display: block;
    color: var(--ik-muted);
    font-size: 0.85em;
}

.ik-tour__from {
    display: block;
    color: var(--ik-muted);
    font-size: 0.85rem;
    line-height: 1;
}

/* Horní hranice ceny — doplněk k té hlavní, ne rovnocenný údaj. */
.ik-tour__to {
    display: block;
    color: var(--ik-muted);
    font-size: 0.85rem;
    line-height: 1.2;
}

/*
 * The `mapa` article's clickable island map — replaces the old site's
 * jQuery ImageMapster/Slimbox combo (see ContentFormatter::replaceIslandMap()).
 * 12 invisible tiles laid over the base image in a 4×3 grid, in source order
 * (A1..D1, A2..D2, A3..D3), so plain CSS Grid auto-placement lines each one
 * up with its own region — no coordinates needed in the markup.
 */
.ik-island-map {
    position: relative;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: repeat(3, 1fr);
    max-width: 700px;
    /* Real image ratio (700×254) — the grid has no other content to size
       itself by, since the image below is taken out of flow on purpose:
       an absolutely positioned child is not a grid item, so it never
       competes with the 12 tiles for auto-placed cells. */
    aspect-ratio: 700 / 254;
}

.ik-island-map img {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
}

.ik-island-map__tile {
    position: relative;
    border-radius: 2px;
}

.ik-island-map__tile:hover,
.ik-island-map__tile:focus-visible {
    background-color: rgba(var(--bs-danger-rgb), 0.35);
    outline: none;
}
