/* Self-hosted brand fonts. fortem.ro's app.css declares these same @font-face families but points at
   www.fortem.ro/fonts, which is cross-origin (blocked by CORS) when the app is not served from that
   host. Re-declaring them here with local URLs (site.css loads after app.css, so these win) keeps the
   fonts same-origin everywhere and lets the PWA cache them for offline use. */
@font-face {
    font-family: 'IBMPlexSans-Light';
    src: url('../fonts/IBMPlexSans-Light.ttf') format('truetype');
    font-display: swap;
}
@font-face {
    font-family: 'IBMPlexSans-Regular';
    src: url('../fonts/IBMPlexSans-Regular.ttf') format('truetype');
    font-display: swap;
}
@font-face {
    font-family: 'IBMPlexSans-Medium';
    src: url('../fonts/IBMPlexSans-Medium.ttf') format('truetype');
    font-display: swap;
}
@font-face {
    font-family: 'IBMPlexSans-SemiBold';
    src: url('../fonts/IBMPlexSans-SemiBold.ttf') format('truetype');
    font-display: swap;
}
@font-face {
    font-family: 'NeueHaasDisplay-Light';
    src: url('../fonts/NeueHaasDisplay-Light.ttf') format('truetype');
    font-display: swap;
}
@font-face {
    font-family: 'NeueHaasDisplay-Medium';
    src: url('../fonts/NeueHaasDisplay-Medium.ttf') format('truetype');
    font-display: swap;
}

/* Bootstrap Icons font. fortem.ro's bootstrap-icons.css declares this @font-face pointing at
   www.fortem.ro/fonts, which is cross-origin — blocked by our CSP (no font-src, so default-src 'self'
   wins) and unavailable offline. site.css loads after that stylesheet, so re-declaring the same family
   with a local URL wins; the glyph classes (.bi-*) from the inherited CSS then render same-origin. */
@font-face {
    font-family: 'bootstrap-icons';
    src: url('../fonts/bootstrap-icons.woff2') format('woff2'),
         url('../fonts/bootstrap-icons.woff') format('woff');
    font-display: block;
}

/* Always reserve the vertical scrollbar's space so centered content (and the role-nav) doesn't shift
   horizontally when navigating between a short page and a page tall enough to scroll. */
html {
    scrollbar-gutter: stable;
}

/* The header reproduces fortem.ro's markup; their custom.css pins it with position: fixed and
   compensates on each page with hero margins (155px desktop, 59px mobile). Our pages have no hero
   classes, so apply the same offsets on the body. */
body {
    padding-top: 155px;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    font-family: 'IBMPlexSans-Regular', 'IBM Plex Sans', system-ui, -apple-system, sans-serif;
}

@media (max-width: 1200px) {
    body {
        padding-top: 59px;
    }
}

/* Regulament text is stored as plain text; keep the author's line breaks. */
.regulament-text {
    white-space: pre-line;
}

/* Inline regulament disclosure on the home page: <details>-based toggle, so opening and closing
   keeps the scroll position without any JS. */
.regulament-disclosure summary {
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    cursor: pointer;
    user-select: none;
    color: #0d6efd;
    text-decoration: underline;
}

.regulament-disclosure summary::-webkit-details-marker {
    display: none;
}

.regulament-disclosure-caret {
    font-size: 0.75em;
    transition: transform .15s;
}

.regulament-disclosure[open] > summary .regulament-disclosure-caret {
    transform: rotate(180deg);
}

.regulament-panel {
    max-width: 40rem;
    margin-left: auto;
    margin-right: auto;
    padding: 1rem 1.25rem;
    background: rgba(255, 255, 255, .92);
    border: 1px solid rgba(32, 42, 64, .12);
    border-radius: 0.7rem;
}

body > main {
    flex: 1 0 auto;
}

/* fortem.ro's app.css declares the brand @font-face families but never applies them to body or
   headings, so our pages fall back to the browser default. Apply them here. */
h1, h2, h3, h4, h5, h6, .navbar-brand {
    font-family: 'NeueHaasDisplay-Medium', 'IBMPlexSans-SemiBold', system-ui, sans-serif;
}

/* Session controls slotted into the fortem.ro header (top-bar-left on desktop, next to the
   hamburger on mobile). */
.account-controls {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
}

/* app.css center-aligns table cells; restore left-aligned scanning, add row hover and a lighter grid. */
.table > :not(caption) > * > * {
    text-align: left;
    vertical-align: middle;
}

.table tbody tr:hover > * {
    background-color: rgba(32, 42, 64, .04);
}

/* Every data table sits in a .table-responsive wrapper, so a table wider than the screen scrolls inside
   its own box instead of pushing the page sideways. Below the lg breakpoint the cells also stop wrapping:
   left to wrap, a nine-column table squeezes into unreadable slivers rather than scrolling, because its
   min-content width then fits the viewport. */
@media (max-width: 991.98px) {
    .table-responsive .table {
        white-space: nowrap;
    }
}

/* A touch device draws no scrollbar, so a table with columns past the right edge looks like it simply
   ends there. table-scroll-hint.js marks the wrappers that actually overflow; only those get the cue. */
.table-responsive.is-scrollable {
    position: relative;
}

.table-responsive.is-scrollable::after {
    content: 'Trageți tabelul lateral pentru restul coloanelor →';
    display: block;
    padding-top: 0.35rem;
    color: #5b6472;
    font-size: 0.8rem;
}

.table .num {
    text-align: right;
}

/* Tap targets. A default Bootstrap checkbox is 16×16, below the 24×24 minimum a finger needs — and on
   the public forms every consent is a checkbox, so this is the difference between ticking the box and
   ticking the box on the third try. The padding compensations keep the label aligned with the bigger box. */
.form-check-input {
    width: 1.5rem;
    height: 1.5rem;
    margin-top: 0.05rem;
}

.form-check {
    padding-left: 2.1rem;
    min-height: 1.5rem;
}

.form-check .form-check-input {
    margin-left: -2.1rem;
}

.form-check-inline {
    margin-right: 1.25rem;
}

/* The "Deschide" link next to a consent is a target of its own, sitting right beside a checkbox it must
   not be mistaken for; give it room in both directions. */
.form-check > a {
    display: inline-block;
    padding: 0.2rem 0.4rem;
    margin-left: 0.1rem;
}

/* The inherited header's hamburger draws as three 30×20 lines — a target under half the size a thumb
   needs, on every page of the app. */
.mobile-menu-btn {
    display: inline-flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 5px;
    min-width: 44px;
    min-height: 44px;
}

/* Status badges inherit 11.2px from the brand CSS, which is below the readable floor for the one word
   that carries a row's meaning. */
.badge {
    font-size: 0.8125rem;
}

/* Footer links are 21px of text on their own line; padding lifts them over the 24px target minimum. */
.site-footer a {
    display: inline-block;
    padding-block: 0.15rem;
}

.top-bar-link,
.alert-link {
    display: inline-block;
    padding-block: 0.15rem;
}

/* .small is 0.875em, so a .small inside a .small compounds down to 11px — which is where the
   "Subdistribuitor al …" and "contul dvs." captions ended up. An absolute size cannot compound. */
.small,
small {
    font-size: 0.875rem;
}

/* A <summary> is the control that opens its section, so it needs the same room as any other target. */
summary {
    padding-block: 0.25rem;
}

/* The inherited brand CSS injects an icon-font glyph via ::before on buttons; it has no icon font on
   our pages, so it renders as an empty "tofu" box. Suppress it — we add button icons explicitly. */
.btn::before,
.btn::after {
    content: none !important;
}

/* The inherited CSS hardcodes oversized, uppercase button padding. Restore Bootstrap's default sizing
   (explicit padding wins over the inherited rule since site.css loads last), and re-declare the size
   modifiers so .btn-sm / .btn-lg keep their own proportions. */
.btn {
    padding: 0.375rem 0.75rem;
    font-size: 1rem;
    text-transform: none;
    letter-spacing: normal;
    min-width: 0;
}

.btn-sm {
    padding: 0.25rem 0.5rem;
    font-size: 0.875rem;
}

.btn-lg {
    padding: 0.5rem 1rem;
    font-size: 1.25rem;
}

/* Role navigation — a segmented navy control that hugs its content and scrolls on narrow screens,
   replacing Bootstrap's off-brand blue nav-pills. Anchors keep their .nav-link/.active classes; these
   rules win on specificity (and .nav-pills is gone, so Bootstrap's pill styling no longer applies). */
.role-nav {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px;
    max-width: 100%;
    padding: 5px;
    border-radius: 999px;
    background: rgba(32, 42, 64, .06);
}

/* Wrapped over several rows — which is what a nine-item admin nav does on a phone — a pill radius reads
   as a blob rather than a control, so the corners tighten once the strip is no longer a single row. */
@media (max-width: 991.98px) {
    .role-nav {
        border-radius: 1rem;
    }
}

.role-nav a,
.role-nav summary {
    white-space: nowrap;
    padding: 0.5rem 0.9rem;
    border-radius: 999px;
    font-size: 0.92rem;
    color: #5b6472;
    text-decoration: none;
    transition: color .15s, background-color .15s, box-shadow .15s;
}

.role-nav a:hover,
.role-nav summary:hover {
    color: #202a40;
    background: rgba(32, 42, 64, .10);
}

.role-nav a.active,
.role-nav a.active:hover,
.role-nav summary.active,
.role-nav summary.active:hover {
    color: #fff;
    background: #202a40;
    font-family: 'IBMPlexSans-Medium', 'IBM Plex Sans', system-ui, sans-serif;
    box-shadow: 0 1px 2px rgba(16, 20, 30, .18);
}

.role-nav a:focus-visible,
.role-nav summary:focus-visible {
    outline: 2px solid #202a40;
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .role-nav a,
    .role-nav summary {
        transition: none;
    }
}

/* Sub-list dropdown inside the role nav (e.g. admin "Ambasadori"). <details>-based: works
   without JS; nav.js only adds close-on-outside-click. */
.role-nav .nav-dropdown {
    position: relative;
}

.role-nav summary {
    list-style: none;
    cursor: pointer;
    user-select: none;
}

.role-nav summary::-webkit-details-marker {
    display: none;
}

.nav-dropdown-caret {
    font-size: 0.7em;
    transition: transform .15s;
}

.role-nav .nav-dropdown[open] > summary .nav-dropdown-caret {
    transform: rotate(180deg);
}

.role-nav .nav-dropdown-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 1050;
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: max-content;
    padding: 5px;
    background: #fff;
    border: 1px solid rgba(32, 42, 64, .12);
    border-radius: 0.9rem;
    box-shadow: 0 8px 24px rgba(16, 20, 30, .14);
}

/* Stat cards — one reusable tile for every dashboard KPI (admin + distributor share this).
   The whole tile is a link to the underlying list, with a tinted icon disc as a visual anchor. */
.stat-card {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    height: 100%;
    padding: 1rem 1.15rem;
    background: #fff;
    border: 1px solid rgba(32, 42, 64, .10);
    border-radius: 0.7rem;
    color: inherit;
    text-decoration: none;
    transition: box-shadow .15s, transform .15s, border-color .15s;
}

.stat-card:hover {
    color: inherit;
    border-color: rgba(32, 42, 64, .18);
    box-shadow: 0 4px 14px rgba(16, 20, 30, .10);
    transform: translateY(-2px);
}

/* Same tile, but not a link (no hover affordance) — for dashboards whose KPIs have no drill-down. */
.stat-card.stat-static:hover {
    border-color: rgba(32, 42, 64, .10);
    box-shadow: none;
    transform: none;
}

.stat-icon {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 50%;
    background: rgba(32, 42, 64, .07);
    color: #202a40;
    font-size: 1.2rem;
}

.stat-body {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
    min-width: 0;
}

.stat-label {
    font-size: 0.8rem;
    color: #5b6472;
}

.stat-value {
    font-size: 1.6rem;
    font-weight: 600;
    font-family: 'IBMPlexSans-SemiBold', 'IBM Plex Sans', system-ui, sans-serif;
    color: #202a40;
}

.stat-sub {
    margin-top: 0.1rem;
    font-size: 0.8rem;
    color: #5b6472;
}

.stat-warning .stat-icon {
    background: rgba(153, 116, 4, .14);
    color: #997404;
}

.stat-warning .stat-value {
    color: #997404;
}

/* Small role pill shown next to the signed-in user's name in the header. */
.role-badge {
    background: rgba(32, 42, 64, .08);
    color: #202a40;
    font-weight: 500;
}

/* Empty-state block — a muted icon + one line, used where a list has no rows yet. */
.empty-state i {
    font-size: 2rem;
    opacity: .45;
}

/* Public claim flow: 3-step progress indicator (Cod → Factură → Voucher). */
.claim-steps {
    display: flex;
    gap: 0.4rem;
    margin: 0 0 1.5rem;
    padding: 0;
    list-style: none;
    counter-reset: step;
}

.claim-steps li {
    flex: 1 1 0;
    display: flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.4rem 0.25rem;
    font-size: 0.85rem;
    color: #9aa1ac;
    border-top: 3px solid rgba(32, 42, 64, .12);
}

.claim-steps li span {
    display: grid;
    place-items: center;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    background: rgba(32, 42, 64, .10);
    color: #5b6472;
    font-size: 0.8rem;
    font-weight: 600;
}

.claim-steps li.active {
    color: #202a40;
    border-top-color: #202a40;
    font-weight: 500;
}

.claim-steps li.active span {
    background: #202a40;
    color: #fff;
}

.code-input {
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
}

.code-input::placeholder {
    letter-spacing: normal;
    text-transform: none;
}

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

    .stat-card:hover {
        transform: none;
    }
}

.form-narrow {
    max-width: 420px;
}

/* Page width utilities (kept in CSS so templates avoid inline styles, which the CSP blocks). */
.mw-460 { max-width: 460px; }
.mw-480 { max-width: 480px; }
.mw-520 { max-width: 520px; }
.mw-560 { max-width: 560px; }
.mw-640 { max-width: 640px; }
.mw-720 { max-width: 720px; }

.campaign-image-thumb {
    max-width: 320px;
}

/* The voucher code on the receipt, which the buyer reads out or copies down. Wrapped across two lines
   it is easy to transcribe wrongly, so it stays on one and the size follows the viewport instead. The
   ceiling is what fits the widest form of the code — the one carrying an ambassador group — inside the
   520px column; the floor keeps it legible on a 320px phone. */
.voucher-code {
    white-space: nowrap;
    font-size: clamp(0.8rem, 4.2vw, 1.5rem);
}

/* Campaign key visual shown whole, next to the page content — the layout the client approved in
   Aug 2026. The visuals are portrait infographics explaining the campaign mechanics, so the earlier
   faded backdrop made them unreadable. Two columns from lg up, stacked below that with the visual
   first, which is also the order the client picked for phones. The split rule needs :has(); where a
   browser lacks it the page simply stacks, which is the mobile layout and still correct. */
.kv-layout {
    display: grid;
    /* Explicit minmax(0, 1fr) rather than the implicit auto track: a grid item's min-width is auto, so
       the intrinsic width of the visual (the masters run several thousand pixels wide) would set the
       track's floor and push the whole page into horizontal scrolling on a phone. */
    grid-template-columns: minmax(0, 1fr);
    gap: 2rem;
}

.kv-visual img {
    display: block;
    width: 100%;
    /* Bootstrap's reboot does not cap image width globally, only .img-fluid does. */
    max-width: 100%;
    height: auto;
    border-radius: 0.5rem;
}

@media (min-width: 992px) {
    .kv-layout:has(.kv-visual) {
        grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
        align-items: start;
    }

    /* The width caps keep the form readable, but the auto margins that centre it on a phone would
       leave it floating in the middle of its column, visibly out of line with the visual beside it. */
    .kv-layout:has(.kv-visual) .kv-content {
        margin-inline: 0;
    }
}

/* Faint full-bleed backdrop showing the active campaign's image on the campaigns list. At most one
   campaign is ever ACTIVE at a time (non-overlap rule), so at most one of these renders per page. */
.campaign-background-image {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: -1;
    opacity: 0.15;
}

/* Bootstrap table cells are transparent, so on the pages carrying that backdrop the campaign photo
   shows through the rows. Rows a cash desk reads a code off must stand on a plain surface. */
.table {
    --bs-table-bg: #fff;
}

.cookie-policy-content {
    white-space: pre-wrap;
}

.privacy-policy-content {
    white-space: pre-wrap;
}

.legal-text-version-content {
    white-space: pre-wrap;
}

.distributor-results {
    z-index: 1000;
    max-width: 480px;
}
