:root {
    color-scheme: light;
    --panel-border: rgba(15, 23, 42, 0.08);
    --text: #102230;
    /* Brand primary and its derived shades. Buttons darken to -hover and
       -active; -rgb feeds rgba() tints and Bootstrap's *-rgb variables.
       Change all of them together when tuning the hue. */
    --brand-red: #FF6100;
    --brand-red-hover: #E05D0C;
    --brand-red-active: #CE5A13;
    --brand-red-rgb: 255, 97, 0;
    /* Text-safe orange for normal-size text/links on light backgrounds:
       #FF6100 is only 3.01:1 on white (AA needs 4.5:1); these pass at
       4.79:1 / 6.85:1. The bright orange stays for large display text,
       buttons and decoration. Mirrors the --brand-blue-text precedent. */
    --brand-red-text: #C24E00;
    --brand-red-text-hover: #9A3E00;
    /* One step darker than -text: plain links sitting directly on the wash
       backgrounds, where #C24E00 measures 4.49:1 - a hair under AA. */
    --brand-red-text-wash: #B84A00;
    /* Display orange for .text-primary text (large headings, prices): one
       notch darker than #FF6100 so large text clears AA's 3:1 on bg-light
       (3.23:1) as well as white (3.40:1); #FF6100 was 2.86:1 on bg-light. */
    --brand-red-display: #F05A00;
    /* Owner-confirmed secondary palette (docs/guides/brand.md): the navy
       pair for large dark surfaces (lifted -> deep, as in the ad canvas)
       and the light blue as a dark-surface accent (too faint for text on
       light backgrounds — use #047BBE there instead). */
    --brand-navy: #031637;
    --brand-navy-deep: #010717;
    /* Royal navy for headings on light backgrounds, matched to the owners'
       ad creatives (headline navy #003060-#183060) - brighter than the
       near-black --brand-navy surface pair. 13.9:1 on white. */
    --brand-navy-heading: #0A2A5E;
    --brand-blue: #67C6FC;
    --brand-blue-rgb: 103, 198, 252;
    /* #0473B1, not the old #047BBE: the /televiziya channel badges put this
       on the blue wash, where #047BBE was 4.30:1 (AA small text needs 4.5). */
    --brand-blue-text: #0473B1;
    /* The one brand-blue info tint for washed backgrounds (blocks, price
       boxes, count pills) — consolidated from per-spot .08/.10/.12 alphas. */
    --brand-blue-wash: rgba(103, 198, 252, .10);

    /* Theme Bootstrap to the brand so its components/utilities produce the
       design's values directly: .rounded-* / .btn / .alert pick up the brand
       radius scale (5/10/15px), .shadow renders the design's card shadow. */
    --bs-border-radius: .3125rem;
    --bs-border-radius-lg: .625rem;
    --bs-border-radius-xl: .9375rem;
    --bs-box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.15);
    --bs-primary: var(--brand-red);
    --bs-primary-rgb: var(--brand-red-rgb);
    /* Full system stack, no webfont: Plus Jakarta Sans shipped no Bulgarian
       glyphs, so Cyrillic always fell back to the OS font anyway; dropping it
       removed the mixed-font lines, the FOUT and 15 woff2 requests. */
    --brand-font: var(--bs-font-sans-serif);

    /* Feature-list marker family: one SVG stroke style (2.2/16, round caps)
       so the checkmark and the download/upload arrows sit visually equal -
       text glyphs (✓, ↓) render with different weights per OS font. Stroke
       #FF6100 = --brand-red (data URIs cannot read CSS variables); the up
       arrow is the down arrow flipped at use site. */
    --icon-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M2.5 8.5 6.5 12.5 13.5 3.5' stroke='%23FF6100' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    --icon-arrow-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M8 2.5v11M3.5 9 8 13.5 12.5 9' stroke='%23FF6100' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

* {
    box-sizing: border-box;
}

/* Always show the vertical scrollbar so layout doesn't shift horizontally
   between short (no scrollbar) and long (scrollbar) pages. */
html {
    overflow-y: scroll;
}

body {
    margin: 0;
    min-height: 100vh;
    font-family: var(--brand-font);
    color: #000;
    background: linear-gradient(180deg, #F9FAFB 0%, #FFFFFF 100%) fixed;
    /* Sticky footer: main grows (see below) so short pages (/plashtane)
       don't leave a white gap under the navy footer. */
    display: flex;
    flex-direction: column;
}

/* Headings default to the ad-matched royal navy instead of body black
   (Q24 colour adaptation). Class-set colours out-specify this, so the
   orange display headings (.text-primary, .site-card-header) and the
   white ones on dark bands (.text-white) are unaffected. */
h1, h2, h3, h4, h5, h6 {
    color: var(--brand-navy-heading);
}

/* ── Site Header ──────────────────────────────────────────── */

.site-header {
    background: #fff;
    width: 100%;
    display: flex;
    flex-direction: column;
}

.site-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

/* Top bar */
.site-header__topbar {
    padding: 11px 0;
}

.site-header__topbar .site-header__inner {
    height: 19px;
    /* Same 1fr/auto/1fr grid as the main row below: the topnav centers on
       the page axis, and under squeeze the grid pushes it off-center
       instead of letting it slide under the phone number (which the old
       absolute left:50% centering did in the 992–1100px band). The padded
       links are taller than the 19px bar; align-items re-centers them. */
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    /* Pin the single row track to the 19px bar height — otherwise it sizes
       to the 35px padded links and re-centers everything ~2px lower. */
    grid-template-rows: 100%;
    align-items: center;
}

.site-header__topbar .lang-switcher {
    justify-self: end;
}

.site-header__contact {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 500;
    font-size: 1rem;
    line-height: 17px;
    color: #000;
}

.site-header__contact a {
    text-decoration: none;
    color: #000;
}

.lang-switcher {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    border: 1px solid #ccc;
    border-radius: 4px;
    padding: 1px 7px;
}

.lang-switcher a {
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-decoration: none;
    /* Black at rest; hover previews the selected orange (same pattern
       as the topnav). */
    color: #000;
    padding: 1px 0;
    transition: color 0.15s;
}

.lang-switcher a:hover {
    color: var(--brand-red-text);
    text-decoration: none !important;
}

.lang-switcher a.is-active {
    color: var(--brand-red-text);
    font-weight: 700;
}

.lang-switcher__sep {
    color: #ccc;
    font-size: 1rem;
    line-height: 1;
}

.lang-switcher--mobile {
    display: flex;
    width: fit-content;
    margin: 1rem auto;
    padding: 0.35rem 1.25rem;
    border-radius: 6px;
    gap: 8px;
}

.lang-switcher--mobile a {
    font-size: 1rem;
    padding: 0.25rem 0.35rem;
}

.lang-switcher--mobile .lang-switcher__sep {
    font-size: 1rem;
}

.site-header__topnav {
    display: flex;
    align-items: center;
    /* Spacing lives in the per-link padding so the whitespace is clickable. */
    gap: 0;
    justify-self: center;
}

.site-header__topnav a {
    display: flex;
    align-items: center;
    gap: 6px;
    /* Bold at all times: the AA-safe darker orange needs the thicker
       strokes to stay readable, and a constant weight can't nudge
       neighbouring links the way state-dependent bolding would. */
    font-weight: 700;
    font-size: 16px;
    line-height: 19px;
    color: var(--brand-navy-heading);
    text-decoration: none;
    white-space: nowrap;
    padding: 8px 12px;
}

/* The topnav differentiates by colour only — no underline on hover or
   active (the main nav below owns the underline-when-active look; mixing
   the two treatments in one header read as inconsistent). */
.site-header__topnav a:hover,
.site-header__topnav a.is-active {
    color: var(--brand-red-text);
}

/* Divider */

.site-header__divider {
    height: 1px;
    background: rgba(0, 0, 0, 0.2);
}

/* Main nav */
.site-header__mainnav {
    padding: 10px 0;
}

.site-header__mainnav .site-header__inner {
    height: 50px;
}

/* On desktop the main row becomes a 1fr/auto/1fr grid so the nav centers on
   the page axis — the same axis the (absolutely centered) topnav sits on;
   with flex space-between it centered in the leftover space between the
   unequal logo and promo button, visibly off the topnav's axis. Grid (vs the
   topnav's absolute trick) degrades by pushing, not overlapping, when the
   992–1199px squeeze leaves less than a logo's width per side. */
@media (min-width: 992px) {
    .site-header__mainnav .site-header__inner {
        display: grid;
        grid-template-columns: 1fr auto 1fr;
        align-items: center;
    }

    .site-header__promo-btn {
        justify-self: end;
    }
}

.site-header__logo {
    display: flex;
    align-items: center;
    gap: 15px;
    text-decoration: none;
    flex-shrink: 0;
    /* No fixed width: the icon + wordmark are ~264px, and a narrower fixed
       box just overflows into the nav (the logo used to be width: 220px). */
}

.site-header__logo-icon {
    flex-shrink: 0;
    width: 37px;
    height: 32px;
}

.site-header__logo-icon img {
    display: block;
    width: 100%;
    height: 100%;
}

.site-header__logo-text {

    font-weight: 800;
    font-size: 30px;
    line-height: 38px;
    color: var(--brand-navy-heading);
    white-space: nowrap;
}

.site-header__logo-net {
    color: var(--brand-red);
}

.site-header__nav {
    display: flex;
    align-items: center;
    /* Spacing lives in the per-link padding so the whitespace is clickable. */
    gap: 0;
}

.site-header__nav a {
    font-weight: 700;
    font-size: 16px;
    line-height: 24px;
    color: var(--brand-navy-heading);
    text-decoration: none;
    white-space: nowrap;
    padding: 8px 12px;
    /* Reserve the underline space on every link so activating one only changes
       its colour — no height change or shift. */
    border-bottom: 2px solid transparent;
}

/* Hover previews exactly what clicking yields — the underline appears,
   text keeps its colour (no orange flash that the active state then
   lacks). The explicit colour is load-bearing: the global a:hover ties
   this selector's specificity and comes later in the file, so without it
   the text flashes the link orange. */
.site-header__nav a:hover {
    color: var(--brand-navy-heading);
    border-bottom-color: var(--brand-red);
}

.site-header__nav a.is-active {
    /* Navy text + bright brand underline: the underline is a non-text
       indicator (3:1 suffices), so it keeps the vivid orange the AA-safe
       text shade can't. */
    color: var(--brand-navy-heading);
    border-bottom-color: var(--brand-red);
}

/* ── Buttons ─────────────────────────────────────────────
   Buttons compose Bootstrap's .btn — markup is `btn btn-primary`, sizes come
   from Bootstrap's own .btn-sm/.btn-lg. The classes below only remap the
   .btn variables to the brand; radius comes from the themed
   --bs-border-radius. Without the .btn base class these do nothing. */

.btn:not(.btn-sm):not(.btn-lg) {
    /* Brand default geometry: 13px + 1rem × 1.5 line + 13px = the 50px-tall
       button the design uses. The :not() guards keep Bootstrap's own size
       modifiers working (a plain `.btn` override would out-cascade them). */
    --bs-btn-padding-y: .8125rem;
    --bs-btn-padding-x: 1.5rem;
}

.btn {
    --bs-btn-font-weight: 600;
}

.btn-primary {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--brand-red);
    --bs-btn-border-color: var(--brand-red);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--brand-red-hover);
    --bs-btn-hover-border-color: var(--brand-red-hover);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--brand-red-active);
    --bs-btn-active-border-color: var(--brand-red-active);
    --bs-btn-disabled-color: #fff;
    --bs-btn-disabled-bg: var(--brand-red);
    --bs-btn-disabled-border-color: var(--brand-red);
    --bs-btn-focus-shadow-rgb: var(--brand-red-rgb);
}

/* The white/blue outline counterpart (device "rent" CTA). */
.btn-secondary {
    --bs-btn-border-width: 2px;
    --bs-btn-color: var(--brand-blue-text);
    --bs-btn-bg: #fff;
    --bs-btn-border-color: var(--brand-blue-text);
    --bs-btn-hover-color: var(--brand-blue-text);
    --bs-btn-hover-bg: var(--brand-blue-wash);
    --bs-btn-hover-border-color: var(--brand-blue-text);
    --bs-btn-active-color: var(--brand-blue-text);
    --bs-btn-active-bg: var(--brand-blue-wash);
    --bs-btn-active-border-color: var(--brand-blue-text);
    --bs-btn-focus-shadow-rgb: var(--brand-blue-rgb);
}

.btn-outline-primary {
    --bs-btn-color: var(--brand-red);
    --bs-btn-border-color: var(--brand-red);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--brand-red);
    --bs-btn-hover-border-color: var(--brand-red);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--brand-red-active);
    --bs-btn-active-border-color: var(--brand-red-active);
    --bs-btn-focus-shadow-rgb: var(--brand-red-rgb);
    --bs-btn-disabled-color: #ccc;
    --bs-btn-disabled-border-color: #ccc;
    --bs-btn-disabled-opacity: 1;
}

/* Reusable wash — colours any block with the brand-blue info tint. */
.bg-brand-blue-wash {
    background: var(--brand-blue-wash);
}

/* Reusable brand-blue text — pairs with .bg-brand-blue-wash. */
.text-brand-blue {
    color: var(--brand-blue-text);
}

/* Reusable AA-safe brand-red text — the .text-brand-blue counterpart, for
   normal-size text where .text-primary's #FF6100 (3.01:1) fails AA. */
.text-brand-red {
    color: var(--brand-red-text);
}

/* Dimmed body text that may contain links: a solid colour instead of
   .opacity-75 — element opacity caps every child, so even an AA-safe
   link inside a .opacity-75 paragraph renders at ~3.2:1. #404040 is
   exactly 75%-black over white, so the text itself looks identical. */
.text-dim {
    color: #404040;
}

/* Screen-reader-only content (the Bootstrap helper; frontend-base.css
   carries no Bootstrap helpers). */
.visually-hidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

/* Working-hours pills (/kontakti): a 10% success/danger tint pre-mixed
   over white, opaque so the pills look identical on every card wash. */
.bg-success-wash {
    background: color-mix(in srgb, var(--bs-success) 10%, #fff);
}

.bg-danger-wash {
    background: color-mix(in srgb, var(--bs-danger) 10%, #fff);
}

/* Reusable brand-tinted callout box (e.g. the TV availability banner). */
.callout-brand {
    background: rgba(var(--brand-red-rgb), .08);
    border: 1px solid rgba(var(--brand-red-rgb), .25);
}

/* Reusable wash — the brand-red counterpart of .bg-brand-blue-wash
   (emphasised price boxes). */
.bg-brand-red-wash {
    background: rgba(var(--brand-red-rgb), .08);
}

/* ── Site card ────────────────────────────────────────────────
   The one public-site card convention (docs/backlog/card-component.md):
   white rounded box with the themed shadow, fs-5 bold brand title, p-4
   body. Named .site-card (not Bootstrap's .card) deliberately — the admin
   uses stock Bootstrap cards, and one name meaning two looks would
   mislead. Put .site-card-header on a real heading tag (h2/h3) so the
   document outline stays sequential; inner layout stays utility classes
   on/inside .site-card-body. */
.site-card {
    background: #fff;
    border-radius: var(--bs-border-radius-xl); /* = rounded-4 */
    box-shadow: var(--bs-box-shadow);          /* = .shadow */
}

.site-card-header {
    margin: 0;
    padding: 1.5rem 1.5rem 0;  /* p-4 sides/top */
    font-size: 1.25rem;        /* = fs-5 */
    font-weight: 700;
    color: var(--brand-red);
}

.site-card-body {
    padding: 1.5rem;           /* = p-4 */
}

.site-card-header + .site-card-body {
    padding-top: 1rem;
}

/* Reusable subtle link — body-coloured with a faint underline, warms to the
   brand on hover. For links inside prose where full brand-red is too loud. */
.link-subtle {
    color: #333;
    text-decoration: underline;
    text-decoration-color: #ccc;
}

.link-subtle:hover {
    color: var(--brand-red-text);
    text-decoration-color: currentColor;
}

/* Reusable anchor-target offset — Bootstrap has no scroll-margin utility. */
.anchor-offset {
    scroll-margin-top: 1.5rem;
}

/* Reusable overflow-x clip — guards full-bleed bands (homepage pricing,
   testimonials) against phone-width horizontal scroll. Bootstrap only has
   overflow-x-hidden, which would turn the band into a scroll container. */
.overflow-x-clip {
    overflow-x: clip;
}

/* Always-visible soft underline for white links on dark/brand backgrounds
   (homepage stats band) — marks them as links without hovering. The
   descender-clearing offset comes from the global `a` rule. */
.link-underline-on-dark {
    text-decoration: underline;
    text-decoration-color: rgba(255, 255, 255, .6);
}

a:hover .link-underline-on-dark {
    text-decoration-color: currentColor;
}

/* Hover-only underline — for links that read as plain text until hovered. */
.hover-underline { text-decoration: none; }
.hover-underline:hover { text-decoration: underline; }

/* Text-coloured link that warms to the brand on hover (card titles etc.). */
.link-plain { color: inherit; text-decoration: none; }
.link-plain:hover { color: var(--brand-red-text); }

/* Classless (prose) links directly on the wash backgrounds - one step
   darker to hold 4.5:1 there. :not([class]) keeps pills, .link-subtle
   and other opted-in recipes out of it. */
.bg-brand-red-wash a:not([class]),
.bg-brand-blue-wash a:not([class]),
.callout-brand a:not([class]),
.callout-info a:not([class]) {
    color: var(--brand-red-text-wash);
}

/* Deepens the (themed) .shadow on hover; !important is needed to
   out-cascade the .shadow utility's own !important. */
.hover-shadow { transition: box-shadow .2s; }
.hover-shadow:hover { box-shadow: 0 8px 32px rgba(0, 0, 0, .18) !important; }
/* Links default to the brand colour so an unstyled link is always visible.
   This used to be `color: inherit`, which made links indistinguishable from
   surrounding body text (and silently invisible). Components that want a
   text-coloured link now opt in explicitly with their own `color`. */
a {
    color: var(--brand-red-text);
    /* Drop every underline below Cyrillic descenders (р, у, ф, д) instead of
       skip-ink chopping gaps into the line. Em-based so it scales with the
       font size (0.3em = the 6px the hero/stats links always used at 20px);
       inherited, so spans inside links pick it up too. */
    text-underline-offset: .3em;
}

a:hover {
    color: var(--brand-red-text-hover);
}

/* .text-primary is display text (headings, prices) - retint it to the
   display orange (see --brand-red-display). !important mirrors how the
   Bootstrap utility itself is generated. Buttons/washes/decoration keep
   the bright #FF6100 via their own variables. */
.text-primary {
    color: var(--brand-red-display) !important;
}

/* Keyboard focus: one visible brand-blue ring everywhere. Only for
   :focus-visible, so mouse clicks stay ring-free. */
:focus-visible {
    outline: 3px solid var(--brand-blue-text);
    outline-offset: 2px;
}

/* On dark/brand surfaces the dark blue ring vanishes - use the light
   brand blue there instead. */
.site-footer :focus-visible,
.hero-slider :focus-visible,
.bg-brand-gradient :focus-visible {
    outline-color: var(--brand-blue);
}

/* Keyboard-only "skip to content" link: first tab stop, parked offscreen
   until focused, then a pill over the header's top-left corner. */
.skip-link {
    position: absolute;
    top: .5rem;
    left: .5rem;
    z-index: 2000;
    padding: .5rem 1rem;
    border-radius: var(--bs-border-radius);
    background: var(--brand-navy);
    color: #fff;
    text-decoration: none;
    transform: translateY(-300%);
}

.skip-link:focus-visible {
    transform: none;
    color: #fff;
}

/* The skip-link target: main takes programmatic focus (tabindex="-1") so
   the next Tab continues from the content, but must not draw the ring. */
main:focus-visible {
    outline: none;
}

main {
    width: 100%;
    /* Takes all leftover height so the footer sits at the viewport bottom
       even when the content is short. */
    flex: 1 0 auto;
}

/* Hamburger button — hidden on desktop */
.site-header__hamburger {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 32px;
    height: 32px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 4px;
    flex-shrink: 0;
}

.site-header__hamburger span {
    display: block;
    width: 100%;
    height: 2px;
    background: #000;
    border-radius: 2px;
    transition: transform 0.25s, opacity 0.25s;
    transform-origin: center;
}

/* Mobile menu — hidden by default */
.site-header__mobile-menu {
    display: none;
    flex-direction: column;
    gap: 0;
    background: #fff;
    border-top: 1px solid rgba(0, 0, 0, 0.1);
    overflow: hidden;
    max-height: 0;
    transition: max-height 0.35s ease;
}

.site-header__mobile-nav,
.site-header__mobile-links {
    display: flex;
    flex-direction: column;
}

.site-header__mobile-nav a {
    padding: 16px 20px;
    font-size: 17px;
    font-weight: 700;
    color: var(--brand-navy-heading);
    text-decoration: none;
    border-bottom: 1px solid rgba(0, 0, 0, 0.07);
}

.site-header__mobile-links {
    border-top: 3px solid rgba(0, 0, 0, 0.07);
    background: #f9f9f9;
}

.site-header__mobile-links a {
    padding: 13px 20px;
    font-size: 1rem;
    font-weight: 400;
    color: #555;
    text-decoration: none;
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}

.site-header__mobile-nav a:hover,
.site-header__mobile-links a:hover {
    background: #f0f0f0;
}

.site-header__mobile-links a svg {
    vertical-align: -2px;
    margin-right: 8px;
}

.site-header__mobile-promo {
    margin: 16px 20px 20px;
}

/* Header squeeze bands. The header row is logo (~264px) + main nav + promo
   button inside the Bootstrap container (1320/1140/960 wide at the xxl/xl/lg
   steps), so the nav link padding and the promo width step down with it. */
@media (max-width: 1399.98px) {
    .site-header__nav a { padding-inline: 8px; }
}

@media (max-width: 1199.98px) {
    .site-header__nav a { padding-inline: 5px; }
    /* The topbar row (phone ~150px + 7 topnav links + lang switcher) fits
       the 960px lg container only with tighter link padding; without this
       the grid pushes the topnav off the page axis. */
    .site-header__topnav a { padding-inline: 7px; }
}

/* Below Bootstrap's lg step the container is 720px — the header row can
   never fit, so this is where the burger takes over (it was 860px, which
   left the 861–991px band overlapping and cut off). */
@media (max-width: 991.98px) {
    .site-header__topbar,
    .site-header__divider-wrap {
        display: none;
    }

    .site-header__mainnav .site-header__inner {
        height: auto;
        padding-top: 12px;
        padding-bottom: 12px;
    }

    .site-header__nav,
    .site-header__promo-btn {
        display: none;
    }

    .site-header__hamburger {
        display: flex;
    }

    .site-header__mobile-menu {
        display: flex;
    }

    /* Hamburger → X animation */
    .site-header__hamburger.is-open span:nth-child(1) {
        transform: translateY(7px) rotate(45deg);
    }
    .site-header__hamburger.is-open span:nth-child(2) {
        opacity: 0;
        transform: scaleX(0);
    }
    .site-header__hamburger.is-open span:nth-child(3) {
        transform: translateY(-7px) rotate(-45deg);
    }

}

/* ── IT Services band (homepage) ─────────────────────────────
   Layout/typography are utilities in home.html.twig; what stays is what
   utilities can't size: the per-feature tinted 62px icon circle and the
   designer crop heights for the tall portrait photo. */

/* Homepage IT band: the service's own emoji, in a fixed-width box so the
   titles beside it line up regardless of glyph width. Replaced the four
   hand-drawn coloured SVG circles when the band became data-driven. */
.it-feature-emoji {
    width: 3.25rem;
    font-size: 2.5rem;
    line-height: 1.2;
    text-align: center;
}

.it-band-photo {
    height: 489px;
}

@media (max-width: 991.98px) {
    .it-band-photo { height: 340px; }
}

@media (max-width: 767.98px) {
    .it-band-photo { height: 245px; }
}

/* ── Testimonials carousel (homepage) ─────────────────────────
   Only the scroll-snap mechanics live here; the card cosmetics are utilities
   in home.html.twig. The __track/__slide/__arrow-- class names are JS hooks
   (frontend.js) — keep them. */

.testimonials__arrow {
    cursor: pointer;
    transition: opacity 0.15s;
}

/* Grayed out when there's nothing more to scroll in that direction. The button's
   `disabled` state also blocks the click (toggled in frontend.js). */
.testimonials__arrow:disabled {
    opacity: 0.25;
    cursor: default;
}

/* Horizontal scroll-snap carousel (replaces Swiper). The track scrolls natively
   (touch / trackpad), and the prev/next arrows drive it with a vanilla scrollBy
   — see frontend.js. */
.testimonials__track {
    flex: 1;
    min-width: 0;
    display: flex;
    gap: 34px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    /* Vertical breathing room so the cards' drop shadow isn't clipped by the
       overflow box; pulled back with a negative margin so section spacing is
       unchanged. */
    padding: 20px 0;
    margin: -20px 0;
    /* The arrows + native swipe are the controls; hide the scrollbar. */
    scrollbar-width: none;
}

.testimonials__track::-webkit-scrollbar {
    display: none;
}

/* Four cards per view on desktop (3 × 34px gaps shared across the row). */
.testimonials__slide {
    flex: 0 0 calc((100% - 3 * 34px) / 4);
    min-width: 0;
    scroll-snap-align: start;
}

/* Two cards per view on tablets. */
@media (max-width: 1024px) {
    .testimonials__track {
        gap: 20px;
    }

    .testimonials__slide {
        flex-basis: calc((100% - 20px) / 2);
    }
}

/* Below md the arrows are hidden (d-none d-md-flex — native swipe is the
   control), so show ~1.3 cards per view: the next one peeks, hinting that
   it scrolls. */
@media (max-width: 767.98px) {
    .testimonials__slide {
        flex-basis: 78%;
    }
}

/* ── Footer ──────────────────────────────────────────────── */

/* Only the brand surface stays custom — the layout is utilities in
   base.html.twig. */
.site-footer {
    background: linear-gradient(180deg, var(--brand-navy) 0%, var(--brand-navy-deep) 100%);
}


/* ── Homepage contact card ───────────────────────────────
   Recomposed onto Bootstrap utilities (d-flex/gap-*/p-*/rounded-3/.shadow +
   .bg-brand-blue-wash) in home.html.twig — only the phone-width full-bleed
   treatment below remains custom. */

@media (max-width: 700px) {
    .home-contact-section .container { padding-inline: 0; }
    .home-contact-card { border-radius: 0 !important; }
}

/* ── Hero slider (homepage) ───────────────────────────────────
   Full-bleed banner band, crossfading between slides (frontend.js drives
   it). Slides are very wide image-only creatives (2880x540) that cover
   the band centred: the central safe zone (800x400 of the creative) is
   visible on every screen down to 320px-wide phones, the sides clip
   progressively on narrower screens. 17.5vw tracks the creative's aspect
   closely, so up to ~2200px-wide screens nearly the whole creative shows;
   past the 400px cap ultra-wide screens trim some of its top/bottom.
   Phones switch to a 12:5 band sized for the slide's mobile creative
   (home.html.twig's <picture> source); a slide without one shows its
   desktop creative there, cropped to the central safe zone as before. */

.hero-slider {
    position: relative;
    height: clamp(210px, 17.5vw, 400px);
    overflow: hidden;
    background: var(--brand-navy);
}

@media (max-width: 767.98px) {
    .hero-slider {
        height: auto;
        aspect-ratio: 12 / 5;
    }
}

.hero-slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity .6s;
}

.hero-slide.is-active {
    opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
    .hero-slide { transition: none; }
}

.hero-slide__link {
    position: absolute;
    inset: 0;
    display: block;
}

.hero-slide__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The dots sit on arbitrary creatives, some light - a small navy pill
   behind just the indicator keeps it visible on any slide. */
.hero-slider__dots {
    position: absolute;
    bottom: .3rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 2;
    display: flex;
    align-items: center;
    gap: .625rem;
    padding: .5rem .75rem;
    border-radius: 50rem;
    background: rgba(3, 22, 55, .45); /* --brand-navy scrim */
}

/* On phones the pill would cover a large share of the short band, so the
   controls move onto a navy strip below the creative instead. */
@media (max-width: 767.98px) {
    .hero-slider:has(.hero-slider__dots) {
        aspect-ratio: auto;
        height: calc(100vw * 5 / 12 + 2.5rem);
    }

    .hero-slider:has(.hero-slider__dots) .hero-slide {
        bottom: 2.5rem;
    }

    .hero-slider__dots {
        bottom: .25rem;
        background: none;
    }
}

/* Prev/next arrows inside the indicator pill, flanking the dots. */
.hero-slider__nav {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    /* Negative block margin: the button target overflows the pill's padding
       instead of inflating it, so the pill stays as slim as dots-only. */
    margin-block: -.375rem;
    padding: 0;
    border: 0;
    border-radius: 50rem;
    background: transparent;
    color: rgba(255, 255, 255, .75);
    cursor: pointer;
    transition: color .2s, background .2s;
}

.hero-slider__nav:hover {
    color: #fff;
    background: rgba(255, 255, 255, .2);
}

/* The play/pause toggle mirrors the slider's autoplay state: the
   hero-slider--autoplay class (the same one that gates the progress
   fill) picks which of the two icons shows. */
.hero-slider__icon-pause {
    display: none;
}

.hero-slider--autoplay .hero-slider__icon-pause {
    display: block;
}

.hero-slider--autoplay .hero-slider__icon-play {
    display: none;
}

.hero-slider__dot {
    width: 1rem;
    height: 1rem;
    padding: 0;
    border: 0;
    border-radius: 50rem;
    background: rgba(255, 255, 255, .55);
    cursor: pointer;
    transition: width .2s;
}

.hero-slider__dot:hover {
    background: rgba(255, 255, 255, .8);
}

/* The active dot is always the 2rem pill - fully filled when autoplay is
   off - so the indicator's total width never changes and the flanking
   arrow buttons stay put. */
.hero-slider__dot.is-active {
    width: 4rem;
    background: #fff;
}

/* Autoplay progress: while autoplay is live the active pill fills over
   the slide interval. frontend.js drives the fill
   (--hero-slider-progress via requestAnimationFrame) and advances the
   slide when the same value reaches 100%, so indicator and timing share
   one source of truth. Deliberately NOT a CSS animation: "no animations"
   OS settings (KDE Instant/GTK) zero those out, which both killed the
   indicator and mad-looped an animationend-driven timer. */
.hero-slider--autoplay .hero-slider__dot.is-active {
    background: linear-gradient(#fff, #fff) left / var(--hero-slider-progress, 0%) 100% no-repeat, rgba(255, 255, 255, .35);
}


/* ── Help / Report form ────────────────────────────────── */

.help-alert {
    padding: .85rem 1.25rem;
    border-radius: .5rem;
    margin-bottom: 1.5rem;
    font-weight: 500;
}

.help-alert--success {
    background: #eafaf1;
    color: #1e8449;
    border: 1px solid #a9dfbf;
}

.help-alert--error {
    background: #fdf3f2;
    color: #c0392b;
    border: 1px solid #f1948a;
}

.help-form__field {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    margin-bottom: 1rem;
}

.help-form__label {
    font-weight: 600;
    font-size: 1rem;
    color: #333;
}

.help-form__input {
    padding: .65rem .9rem;
    border: 1.5px solid #ddd;
    border-radius: .5rem;
    font-size: 1rem;
    outline: none;
    transition: border-color .15s;
    font-family: inherit;
}

.help-form__input:focus {
    border-color: var(--brand-red);
}

.has-error .help-form__input {
    border-color: #e74c3c;
}

.help-form__textarea {
    /* Autogrows with content where field-sizing is supported (Chromium);
       frontend.js provides a JS fallback elsewhere. */
    min-height: 90px;
    max-height: 45vh;
    resize: vertical;
    field-sizing: content;
}

.help-form__error {
    font-size: 1rem;
    color: #e74c3c;
}

/* ── FAQ accordion ─────────────────────────────────────── */

.faq-list {
    display: flex;
    flex-direction: column;
}

.faq-item {
    border-bottom: 1px solid #eee;
}

.faq-item:first-child {
    border-top: 1px solid #eee;
}

/* Now that each category is its own card, the last separator would hang
   between the final question and the card edge. */
.faq-item:last-child {
    border-bottom: none;
}

/* The +/- marker leads the row (like a native <details> triangle), so the
   items sit left-to-right rather than being pushed to opposite edges. */
.faq-item__question {
    display: flex;
    /* flex-start, not center: on a question that wraps to two lines a centred
       marker floats at mid-height instead of sitting on the first line. */
    align-items: flex-start;
    padding: 1.1rem 0;
    font-weight: 600;
    font-size: 1rem;
    cursor: pointer;
    list-style: none;
    gap: 0.75rem;
}

.faq-item__question::-webkit-details-marker { display: none; }

/* The +/- disclosure marker, shared by every <details> recipe (FAQ items,
   the TV channel lists) - the [open] flip below keys on any details parent. */
.details-icon {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    margin-top: 3px;   /* optical centre of the first line (24px line-height) */
    position: relative;
    color: var(--brand-red);
}

.details-icon::before,
.details-icon::after {
    content: '';
    position: absolute;
    background: var(--brand-red);
    border-radius: 2px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.details-icon::before { width: 12px; height: 2px; }
.details-icon::after  { width: 2px; height: 12px; transition: transform .2s; }

details[open] .details-icon::after {
    transform: translate(-50%, -50%) rotate(90deg);
}

/* Indented to line up with the question text rather than the leading +/-
   marker, so an answer visibly belongs to the question above it. */
.faq-item__answer {
    padding: 0 0 1.1rem calc(18px + 0.75rem);
    color: #555;
    line-height: 1.6;
    margin: 0;
}

/* Answers are markdown, so the box holds <p>/<ul> blocks rather than text;
   the last one must not add its own margin below the box's padding. */
.faq-item__answer > :last-child { margin-bottom: 0; }

/* Anchor permalink: a chain icon after the heading (or FAQ question) that owns
   an id, revealed on hover or keyboard focus, so a copyable link exists without
   shouting. Desktop only - there is no hover on touch, and the anchors still
   work for anyone handed the URL.

   Trailing rather than hanging in a left gutter: the cards it appears in use
   the standard 1.5rem padding, which is narrower than the icon itself. */
.permalink {
    display: none;
}

@media (min-width: 768px) {
    .permalink {
        display: inline-flex;
        vertical-align: middle;
        margin-left: 0.4rem;
        color: #bbb;
        text-decoration: none;
        opacity: 0;
        transition: opacity 0.15s, color 0.15s;
    }

    /* Parent-agnostic: headings, the Trio tier pill and the <summary> rows
       (FAQ questions, TV channel-list toggles) all own anchors, and each new
       one should not need its own selector. */
    :hover > .permalink,
    summary:hover .permalink,
    .permalink:focus-visible {
        opacity: 1;
    }

    .permalink:hover {
        color: var(--brand-red-text);
    }
}

/* FAQ category jump links — the /kontakti outline-pill shape, as a recipe
   rather than utilities because the hover/focus states need CSS anyway.
   Underline-free is deliberate here: the pill border already reads as a
   control, unlike a bare link in prose. */
.faq-nav a {
    background: #fff;
    border: 1px solid #ddd;
    border-radius: 50rem;
    padding: 0.35rem 0.9rem;
    color: #333;
    font-weight: 600;
    text-decoration: none;
    transition: color 0.15s, border-color 0.15s;
}

.faq-nav a:hover,
.faq-nav a:focus-visible {
    color: var(--brand-red-text);
    border-color: var(--brand-red);
}

/* ── Product-page hero (Internet, TV, Phone, Trio, Devices, IT, CMS) ──
   The hero composes utilities in markup; this class carries only what
   Bootstrap can't: the design's hero title size (fs-1 caps at 2.5rem).
   The tight line-height keeps the title close to its subtitle. Subtitles
   are muted via text-muted (a colour, not element opacity) so
   brand-coloured links inside them — the trio subtitle has some — keep
   their own colour. */

.hero-title {
    font-size: 3.75rem;
    line-height: 1.2;
}

@media (max-width: 700px) {
    .hero-title { font-size: 2.2rem; }
}

/* ── CMS static pages (about, terms, access-interfaces) ──── */

.cms-content {
    padding-bottom: 3rem;
    font-size: 1.06rem;
    line-height: 1.65;
}

.cms-content h2 {
    font-size: 1.6rem;
    font-weight: 700;
    margin: 2rem 0 .75rem;
}

/* Cards inside CMS content (e.g. the payment page) keep the component
   look — the element-selected .cms-content heading rules below would
   otherwise out-specify .site-card-header. */
.cms-content .site-card-header {
    font-size: 1.25rem;
    margin: 0;
}

.cms-content h3 {
    font-size: 1.3rem;
    font-weight: 700;
    margin: 1.5rem 0 .5rem;
}

.cms-content h4 {
    font-size: 1.1rem;
    font-weight: 600;
    margin: 1.25rem 0 .5rem;
}

.cms-pdf-embed {
    display: block;
    width: 100%;
    height: 700px;
    margin-top: 2rem;
    border: 1px solid #E5E7EB;
    border-radius: 10px;
}

/* ── IT Services Page ─────────────────────────────────────── */

/* Brand gradient band (the IT CTA — markup lives in the it-services-outro
   static page in the DB). */
.bg-brand-gradient {
    background: linear-gradient(180deg, var(--brand-red) 0%, var(--brand-red-hover) 100%);
}

/* Reusable oversized emoji "icon" (IT service cards + the why section in
   the it-services-outro static page). No utility goes this large. */
.emoji-icon {
    font-size: 4rem;
    line-height: 1.5;
    text-align: center;
}

/* Service cards — 3×2 grid. 4 implicit row tracks per card: icon | title |
   desc | features. Each card spans them as a subgrid (below) so the sections
   line up across a row even when a title/description wraps to a different
   number of lines — same technique as the plan and Trio cards. Bootstrap's
   row/col can't express subgrid, so the grid plumbing stays custom; the card
   cosmetics are utilities in the template. */
.it-services-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 2rem;
    grid-auto-rows: auto auto auto auto;
}

.it-service-card {
    grid-row: span 4;
    display: grid;
    grid-template-rows: subgrid;
    row-gap: 1rem;
    align-items: start;
}

.it-service-card__features {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

.it-service-card__features li {
    display: flex;
    gap: .5rem;
    line-height: 1.5;
}

.it-service-card__features li::before {
    content: '';
    flex-shrink: 0;
    width: 1rem;
    height: 1rem;
    margin-top: .25rem;
    background: var(--icon-check) center / contain no-repeat;
}

/* Team cards */

.it-team-card__avatar {
    width: 8rem;
    height: 8rem;
    border-radius: 50%;
    background: #E5E7EB;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 3rem;
    overflow: hidden;
}
.it-team-card__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    display: block;
}

/* Reserve two lines so the roles align across cards with 1- and 2-line names. */
.it-team-card__name {
    min-height: 2lh;
}

/* ── Plan Cards (Internet, Phone) ────────────────────────── */

.plan-cards {
    display: grid;
    column-gap: 1.5rem;
    row-gap: 0;
    /* 4 repeating implicit row tracks per card: name | pricing | features | btn */
    grid-auto-rows: auto auto auto auto;
}

.plan-cards--4 { grid-template-columns: repeat(4, 1fr); }
.plan-cards--3 { grid-template-columns: repeat(3, 1fr); }

/* One or two plans: keep the cards a sensible width and centre them, rather
   than stretching them across the row or hugging the left edge. */
.plan-cards--2 { grid-template-columns: repeat(2, minmax(0, 440px)); justify-content: center; }
.plan-cards--1 { grid-template-columns: minmax(0, 440px); justify-content: center; }

.plan-card {
    /* Gradient replaces the old bar DOM element: accent colour for the top 21px
       (bar), white below. The accent colour at the top corners also fills the
       seam between the bar and the featured ring so no white shows there. */
    background: linear-gradient(to bottom, var(--card-accent, #e5e7eb) 21px, #fff 21px);
    border-radius: 10px;
    box-shadow: 0 0 20px rgba(0,0,0,.15);
    /* Subgrid: spans 4 row tracks in the parent .plan-cards grid so that
       name / pricing / features / btn align across every card in the row. */
    grid-row: span 4;
    display: grid;
    grid-template-rows: subgrid;
    align-items: start;
    padding: calc(21px + 2rem) 1.5rem 1.75rem 2rem;
}

/* ── TV page (two-product model: digital cable + IPTV) ───────
   Everything but this is utilities in tv/list.html.twig. */

/* Numbered channel chips — CSS counters have no utility equivalent; the chip
   cosmetics are utilities on the <li>s. */
.tv-grid {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem;
    padding: 0; margin: 0; list-style: none; counter-reset: tvc;
}
.tv-grid li { counter-increment: tvc; }
.tv-grid li::before { content: counter(tvc); font-weight: 700; color: var(--brand-red); min-width: 1.6rem; }

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

/* Channel lists sit collapsed behind their package's price row; the toggle is
   the FAQ question recipe (leading +/- details-icon, no native marker). The
   deep-link opener in frontend.js expands a list linked to by its anchor. */
.tv-channels__toggle {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    font-weight: 600;
    cursor: pointer;
    list-style: none;
}

.tv-channels__toggle::-webkit-details-marker { display: none; }

.tv-channels[open] > .tv-channels__toggle {
    margin-bottom: 0.75rem;
}

/* ── Trio Packages ───────────────────────────────────────── */

.trio-group {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    column-gap: 1.5rem;
    row-gap: 0;
    /* 4 repeating implicit row tracks per card: name | pricing | features | btn
       (same structure as the plan cards, so the type scale matches). */
    grid-auto-rows: auto auto auto auto;
    margin-bottom: 2rem;
}

.trio-group--2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    width: calc((100% - 3rem) / 3 * 2 + 1.5rem);
    margin-inline: auto;
}

.trio-card {
    background: linear-gradient(to bottom, var(--card-accent, #e5e7eb) 21px, #fff 21px);
    border-radius: 10px;
    box-shadow: 0 0 20px rgba(0,0,0,.15);
    text-align: center;
    /* Subgrid: spans 4 row tracks so name/pricing/features/btn align across cards
       — same structure and scale as the plan cards. */
    grid-row: span 4;
    display: grid;
    grid-template-rows: subgrid;
    align-items: start;
    padding: calc(21px + 2rem) 1.5rem 1.75rem 2rem;
}

/* ── Shared plan/trio card family ─────────────────────────
   The two card types are deliberate siblings (same type scale, features
   list, CTA and featured emphasis), so the identical parts live here once.
   Both templates provide --card-accent (the plan card sets it inline; the
   trio group sets it for its cards). These rules sit after both .plan-card
   and .trio-card so the --featured overrides win the cascade for both. */

.plan-card__name, .trio-card__name {
    font-size: 2.25rem;
    font-weight: 700;
    margin: 0 0 1rem;
    color: var(--brand-navy-heading);
    text-align: center;
}

/* The card highlight (app/plans/_highlight.html.twig): utilities do the
   layout; these cover what Bootstrap has no utility for. */
.plan-highlight__title { color: var(--brand-navy-heading); }
.plan-highlight__text  { text-wrap: balance; }
.plan-highlight__thumb { width: clamp(56px, 22%, 88px); height: auto; }

.plan-card__features, .trio-card__features {
    list-style: none;
    padding: 0;
    margin: 0 0 1.5rem;
    align-self: stretch;
}

/* The trio card centres its text; its features must opt back out. */
.trio-card__features {
    text-align: left;
}

.plan-card__features li, .trio-card__features li {
    padding: .4rem 0 .4rem 1.75rem;
    position: relative;
    font-size: 1.125rem;
    font-weight: 500;
    color: #000;
    line-height: 1.5;
}

.plan-card__features li::before, .trio-card__features li::before {
    content: '';
    position: absolute;
    left: 0;
    top: .7rem;
    width: 1.05rem;
    height: 1.05rem;
    background: var(--icon-check) center / contain no-repeat;
}

/* The download value pops (the datum buyers compare); the sentence, and
   the upload bullet entirely, stay quiet. Plan cards only: the Trio
   bullets are long linked sentences where this reads as noise. */
.plan-card__features .feature-speed--download {
    font-weight: 700;
    font-size: 1.25rem;
}

/* System-generated speed bullets carry direction arrows instead of the
   checkmark - the templates know which line is which, no string sniffing. */
.plan-card__features li.feature-download::before, .trio-card__features li.feature-download::before,
.plan-card__features li.feature-upload::before, .trio-card__features li.feature-upload::before {
    background-image: var(--icon-arrow-down);
}

.plan-card__features li.feature-upload::before, .trio-card__features li.feature-upload::before {
    transform: scaleY(-1);
}

.plan-card__btn, .trio-card__btn {
    display: flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    border-radius: 10px;
    font-size: 1.125rem;
    font-weight: 700;
    height: 59px;
    align-self: end;
}

.plan-card--featured, .trio-card--featured {
    /* Pop the recommended card by making it genuinely TALLER — it sticks out
       above its siblings — rather than scaling it (which would enlarge and
       offset its text, breaking the row-by-row alignment the subgrid gives
       us). The card's own content stays pinned to the shared subgrid rows, so
       name/pricing/features/button still line up across every card; only the
       painted box grows. The accent ring + deeper shadow add the emphasis.
       The box itself is drawn by ::before so it can extend past the grid cell. */
    position: relative;
    background: none;
    box-shadow: none;
    z-index: 1;
}

.plan-card--featured::before, .trio-card--featured::before {
    content: '';
    position: absolute;
    /* Sticks out at the top only; bottom stays flush so the CTA buttons keep a
       shared baseline across all cards. */
    inset: -1.75rem 0 0 0;
    z-index: -1;
    border-radius: 10px;
    background: linear-gradient(to bottom, var(--card-accent, #e5e7eb) 21px, #fff 21px);
    box-shadow: 0 0 0 4px var(--card-accent, var(--brand-red)), 0 20px 56px rgba(0,0,0,.18);
}

/* Hidden on desktop — only shown on stacked/mobile layouts via the media query below. */
.plan-card__badge, .trio-card__badge {
    display: none;
    position: absolute;
    top: .55rem;
    left: 50%;
    transform: translateX(-50%);
    background: var(--brand-red);
    color: #fff;
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    padding: .2rem .65rem;
    border-radius: 999px;
    white-space: nowrap;
    z-index: 1;
}

/* ── Speed disclosure (EU Open-Internet legal notice) ────────
   Shared across every page advertising internet speeds
   (app/_speed_disclosure.html.twig). Only the amber legal-notice palette
   is custom; the geometry is utilities in the partial. */

.speed-disclosure {
    background: #FEFCE8;
    border-left: 4px solid #F0B100;
}

/* Info sibling of .speed-disclosure (the corporate note on /internet):
   same shape, brand-blue wash instead of the legal yellow. */
.callout-info {
    background: var(--brand-blue-wash);
    border-left: 4px solid var(--brand-blue);
}

/* ── Devices ─────────────────────────────────────────────── */

/* Always reserve two lines so one- and two-line names keep the pricing
   boxes (and everything below) aligned across cards. */
/* Product photo atop the card: 'fit'-resized (never cropped) and letterboxed
   into a fixed strip so the sections below align across photo'd cards. */
.device-card__photo {
    height: 180px;
    object-fit: contain;
}

.device-card__name {
    line-height: 1.3;
    min-height: 4.55rem;
}

/* Checkmark feature list (the ::before glyph has no utility equivalent). */
.device-card__features {
    list-style: none;
}

.device-card__features li {
    padding: .25rem 0 .25rem 1.4rem;
    position: relative;
}

.device-card__features li::before {
    content: '';
    position: absolute;
    left: 0;
    top: .5rem;
    width: .95rem;
    height: .95rem;
    background: var(--icon-check) center / contain no-repeat;
}

.device-card__actions .btn {
    /* The buy/rent pair splits the card width equally (flex:1 — flex-fill
       would size by label length) with tighter padding to fit the card.
       Colours come from the shared .btn-primary/.btn-secondary. */
    flex: 1;
    min-width: 0;
    min-height: 52px;
    padding: .5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* ── Responsive additions ────────────────────────────────── */

/* Plan-card squeeze band: in the 960px lg container three cards leave only
   ~230px of content width each, which the nowrap dual price lines (fs-2,
   "50.00 лв/месец") overflow — the row used to clip at the viewport edge.
   Stepping the prices down to Bootstrap's fs-3 curve makes 3-across fit;
   the !important matches the fs-2 utility's own. Four cards can never fit
   this band, so --4 drops to 2 columns here instead. */
@media (min-width: 992px) and (max-width: 1199.98px) {
    .plan-card .fs-2, .trio-card .fs-2 { font-size: calc(1.3rem + .6vw) !important; }
    .plan-cards--4   { grid-template-columns: repeat(2, 1fr); row-gap: 1.5rem; }
}

@media (max-width: 1100px) {
    .it-services-grid { grid-template-columns: repeat(2, 1fr); }
}

/* Below lg the container is 720px — even squeezed prices can't fit three
   across, so the cards stack (was 900px, which left the 901–991px band
   clipping). */
@media (max-width: 991.98px) {
    .plan-cards--3   { grid-template-columns: 1fr; row-gap: 1.5rem; }
    .plan-cards--4   { grid-template-columns: repeat(2, 1fr); row-gap: 1.5rem; }
    .trio-group      { grid-template-columns: 1fr; row-gap: 1.5rem; }
    .trio-group--2   { width: 100%; }

    /* Stacked single column: the featured card must not stick out past its
       neighbours, so it reverts to a normal in-flow box that keeps the accent
       ring — no taller backdrop. Show the "Препоръчан" badge instead. */
    .plan-card--featured, .trio-card--featured {
        background: linear-gradient(to bottom, var(--card-accent, #e5e7eb) 21px, #fff 21px);
        box-shadow: 0 0 0 4px var(--card-accent, var(--brand-red)), 0 0 20px rgba(0,0,0,.12);
    }
    .plan-card--featured::before, .trio-card--featured::before { display: none; }
    .plan-card--featured .plan-card__badge,
    .trio-card--featured .trio-card__badge { display: block; }
}

@media (max-width: 700px) {
    .plan-cards--4       { grid-template-columns: 1fr; }
    .plan-cards--2       { grid-template-columns: minmax(0, 440px); row-gap: 1.5rem; }
    .plan-card__name     { font-size: 1.5rem; }
    .it-services-grid    { grid-template-columns: 1fr; }
}

/* ── News / promo (cards + article prose) ─────────────────── */

.news-card__image {
    height: 200px;
    background-size: cover;
    /* Anchor the top: the imgproxy render already keeps the top of the
       cover (g:no), and cover-scaling into the 200px box must not re-crop
       it back to the middle. */
    background-position: center top;
}

/* Aspect-preserving: the imgproxy render (rt:fit) is never cropped, and small
   historical covers are never stretched up — they show at natural size. */
.news-article-cover__img {
    display: block;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 520px;
    border-radius: 12px;
    margin-inline: auto;
}

.news-article-content {
    font-size: 1.05rem;
    line-height: 1.75;
    color: var(--text);
}
.news-article-content img { max-width: 100%; height: auto; border-radius: 8px; }
.news-article-content h2,
.news-article-content h3 { margin-top: 2rem; }

@media (max-width: 600px) {
    .news-article-cover__img { max-height: 300px; }
}

/* ── Error pages (404 & co. — templates/bundles/TwigBundle) ── */
/* The watermark status code — no utility goes this large. */
.error-page__code {
    font-size: 6rem;
}

/* ── Order Request Form ───────────────────────────────────── */
.order-request-card {
    /* Wide enough for the optional-field placeholders ("Оставете празно,
       ако нямате или не го знаете") in the half-width columns. */
    max-width: 900px;
    margin-inline: auto;
}

/* Plan order: pick which advertised price (open-ended vs 1-year contract).
   A clickable radio card — the border + :has(:checked) state has no utility
   equivalent; its flex layout is utilities in the template. */
.plan-order-price-choice {
    padding: .7rem 1rem;
    border: 2px solid var(--panel-border);
    border-radius: 8px;
    cursor: pointer;
    transition: border-color .15s, background .15s;
}

.plan-order-price-choice:has(input[type="radio"]:checked) {
    border-color: var(--brand-red);
    background: rgba(var(--brand-red-rgb), .06);
}

/* ── Required field marker ───────────────────────────────── */
.required-mark {
    color: var(--brand-red);
    margin-left: 2px;
}

/* ── Anti-bot honeypot ───────────────────────────────────── */
/* The honeypot field (see _form_protection.html.twig) — pulled off-screen rather
   than display:none so bots that skip hidden fields still encounter it, while
   real users never see or tab to it. */
.fp-trap {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Honour the OS "reduce motion" setting: collapse every CSS transition and
   animation (hover fades, the mobile-menu slide, hover-shadow) to instant.
   The near-zero duration (not `none`) keeps transitionend/animationend
   firing for any code that waits on it. The carousel's smooth scrolling is
   handled in frontend.js, which checks the same media query per click. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        transition-duration: .01ms !important;
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        scroll-behavior: auto !important;
    }
}
