/* --------------------------------------------------------------------------
 * F4S additions on top of Falcon.
 *
 * theme.min.css is Falcon's compiled stylesheet and is never edited, so the template
 * can be upgraded by replacing that one file. Everything specific to F4S - the brand
 * mark, the video grid, the player shell and the uploader - lives here and is written
 * with Falcon's own CSS variables so it follows the light/dark theme automatically.
 * -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
 * Brand colour
 *
 * The teal of the logo replaces Falcon's blue as the accent of the whole interface.
 * Falcon reads --falcon-primary(-rgb) for buttons, active navigation, focus rings,
 * progress bars and badges, and --falcon-link-color(-rgb) for links, .btn-link and the
 * pagination - so these variables cover nearly everything; the few places where the
 * template writes the blue directly are overridden further down this file.
 *
 * --f4s-brand is the same colour for F4S's own components. The dark theme uses a lighter
 * tint: the plain teal is too dim on a dark background.
 * ----------------------------------------------------------------------- */
:root {
    --f4s-brand: #19b1b7;
    --f4s-brand-rgb: 25, 177, 183;
    --f4s-brand-dark: #128b90;
    --falcon-primary: #19b1b7;
    --falcon-primary-rgb: 25, 177, 183;
    --falcon-primary-text-emphasis: #10767a;
    --falcon-primary-bg-subtle: #d5f1f2;
    --falcon-primary-border-subtle: #a6e1e4;
    --falcon-link-color: #19b1b7;
    --falcon-link-color-rgb: 25, 177, 183;
    --falcon-link-hover-color: #128b90;
    --falcon-link-hover-color-rgb: 18, 139, 144;
    /* The sidebar writes its own colour for the open page. */
    --falcon-navbar-vertical-default-link-active-color: #19b1b7;
}

[data-bs-theme="dark"] {
    --f4s-brand: #2ecdd3;
    --f4s-brand-rgb: 46, 205, 211;
    --f4s-brand-dark: #19b1b7;
    --falcon-primary: #19b1b7;
    --falcon-primary-rgb: 25, 177, 183;
    --falcon-primary-text-emphasis: #a6e1e4;
    --falcon-primary-bg-subtle: #0d3c3e;
    --falcon-primary-border-subtle: #15595c;
    --falcon-link-color: #2ecdd3;
    --falcon-link-color-rgb: 46, 205, 211;
    --falcon-link-hover-color: #6ee3e7;
    --falcon-link-hover-color-rgb: 110, 227, 231;
    --falcon-navbar-vertical-default-link-active-color: #2ecdd3;
}

/* .progress declares the colour of its bar itself, so it is set there and not on :root.
   A bar with a contextual class (.bg-danger …) still wins over this. */
.progress,
.progress-stacked {
    --falcon-progress-bar-bg: var(--f4s-brand);
}

/* Brand icon (public/assets/brand, built by deploy/scripts/build-brand-assets.php). */
.f4s-brand-icon {
    flex: 0 0 auto;
    border-radius: 22%;
    vertical-align: middle;
}

/* Navbar logo: the image alone, never stretched. */
.f4s-brand-mark {
    width: auto;
    max-width: 100%;
    vertical-align: middle;
}

/* The artwork's deep blue sinks into the dark navbar; lift it slightly there. */
[data-bs-theme="dark"] .f4s-brand-mark {
    filter: brightness(1.3) saturate(1.1);
}

/* Full logo: dark lettering on light themes, white lettering on the dark theme. */
.f4s-logo-dark { display: none; }
[data-bs-theme="dark"] .f4s-logo-light { display: none; }
[data-bs-theme="dark"] .f4s-logo-dark { display: inline-block; }

/* No underline when a link is hovered or focused: the template turns one on for every <a>,
   and the colour change is feedback enough. A link that asks for an underline on purpose
   (.text-decoration-underline) keeps it - that utility is !important. */
a:hover,
a:focus,
a:focus-visible {
    text-decoration: none;
}

/* Table cells are centred vertically further down this file (and by Falcon), which beats
   Bootstrap's .align-top on the table. A table that asks for top alignment gets it back -
   with the same reach as the rule it has to overrule. */
.table.align-top > :not(caption) > * > *,
.card > .table-responsive > .table.align-top > tbody > tr > td {
    vertical-align: top;
}

/* Cells of the encode job table are two lines with a fixed rhythm: the headline (title,
   badge, total, encoder) on a line of its own height, the detail under it. The bars of the
   Status and Time columns then start at the same point in every row of the table. */
.f4s-job-cell {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.f4s-job-cell > :first-child {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 0.5rem;
    min-height: 1.5rem;
}

/* The line a bar sits on, in both columns: same height and same middle, so the bar of the
   Status column and the bar of the Time column are on one line across the table. */
.f4s-bar-line {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 1rem;
}

/* Thin bar of the encode job table: the same shape whether it shows how far a running job
   got or how its time was split between the stages, so the rows line up. The figures are
   in the tooltip of the cell. */
.f4s-bar {
    display: flex;
    width: 6.5rem;
    height: 4px;
    border-radius: 999px;
    overflow: hidden;
    background: var(--falcon-border-color);
}

.f4s-bar > span {
    height: 100%;
    transition: width 0.4s ease-in-out;
}

/* Progress of a running job; the striped version marks a step whose length is unknown. */
.f4s-bar-fill {
    background: var(--f4s-brand);
}

.f4s-bar-indeterminate {
    width: 100%;
    background: linear-gradient(90deg,
        rgba(var(--f4s-brand-rgb), 0.25) 0%, var(--f4s-brand) 50%, rgba(var(--f4s-brand-rgb), 0.25) 100%);
    background-size: 200% 100%;
    animation: f4s-bar-slide 1.4s linear infinite;
}

@keyframes f4s-bar-slide {
    from { background-position: 100% 0; }
    to   { background-position: -100% 0; }
}

.f4s-stage-download { background: rgba(var(--f4s-brand-rgb), 0.35); }
.f4s-stage-gap      { background: transparent; }
.f4s-stage-probe    { background: rgba(var(--f4s-brand-rgb), 0.5); }
.f4s-stage-encode   { background: var(--f4s-brand); }
.f4s-stage-thumbs   { background: rgba(var(--f4s-brand-rgb), 0.5); }
.f4s-stage-package  { background: rgba(var(--f4s-brand-rgb), 0.7); }
.f4s-stage-upload   { background: rgba(var(--f4s-brand-rgb), 0.45); }

/* Page actions in the top bar. On a phone they take a full row of their own under the
   brand - squeezed between the logo and the avatar they wrapped and broke the bar - and
   from md on they return to the same line as the user tools. */
.navbar-top {
    flex-wrap: wrap;
    row-gap: 0.5rem;
}

.navbar-top .f4s-top-actions {
    flex: 0 0 100%;
    justify-content: flex-start;
}

.navbar-top .f4s-top-actions > .btn,
.navbar-top .f4s-top-actions > form > .btn {
    flex: 1 1 auto; /* two buttons share the row instead of hugging the left edge */
}

@media (min-width: 768px) {
    .navbar-top .f4s-top-actions {
        flex: 0 1 auto;
        justify-content: flex-end;
    }

    .navbar-top .f4s-top-actions > .btn,
    .navbar-top .f4s-top-actions > form > .btn {
        flex: 0 0 auto;
    }
}

/* Air under the top bar of the two sidebar layouts (user area and admin panel): without
   it the first block of a page - a row of actions, an alert, a card - sits right against
   the page title. A Bootstrap .row cancels its own top gutter with a negative margin, so
   the space has to come from here to be the same on every page. */
.content > .navbar-top {
    margin-bottom: 1rem;
}

/* A row of buttons: the actions of a page (top bar), of a table row or of a card header.
   Inline buttons only have the collapsed whitespace between them, which reads as "stuck
   together"; this gives them the same gap everywhere and lets them wrap on small screens.
   post_button() renders a <form>, so those are flex items like the buttons themselves. */
.f4s-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
}

.f4s-actions > form {
    margin-bottom: 0;
}

/* The sign-out nav link is a form button, so it needs the link's own text colour. */
.navbar-vertical .nav-link > button,
.navbar-vertical form > .nav-link {
    color: inherit;
    font: inherit;
}

/* --------------------------------------------------------------------------
 * Video thumbnails
 * ----------------------------------------------------------------------- */

/* Fixed 16:9 box so a grid of cards stays aligned whatever the source image is. */
.f4s-thumb {
    position: relative;
    display: block;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: var(--falcon-gray-200);
}

.f4s-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* No picture yet: an icon on a tinted box instead of an empty grey rectangle. */
.f4s-thumb-state {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    color: rgba(var(--f4s-brand-rgb), 0.85);
    background:
        linear-gradient(135deg, rgba(var(--f4s-brand-rgb), 0.16) 0%, rgba(var(--f4s-brand-rgb), 0.05) 100%),
        var(--falcon-emphasis-bg, #fff);
}

.f4s-thumb-state.is-failed {
    color: rgba(230, 55, 87, 0.85);
    background:
        linear-gradient(135deg, rgba(230, 55, 87, 0.16) 0%, rgba(230, 55, 87, 0.05) 100%),
        var(--falcon-emphasis-bg, #fff);
}

.f4s-thumb-state-icon {
    display: flex;
    position: relative;
    z-index: 1;
}

/* A band of light crossing the box: the video is being worked on. */
.f4s-thumb-state.is-working::after,
.f4s-thumb-state.is-uploading::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(100deg,
        transparent 20%, rgba(255, 255, 255, 0.45) 50%, transparent 80%);
    transform: translateX(-100%);
    animation: f4s-thumb-sweep 1.8s ease-in-out infinite;
}

[data-bs-theme="dark"] .f4s-thumb-state.is-working::after,
[data-bs-theme="dark"] .f4s-thumb-state.is-uploading::after {
    background: linear-gradient(100deg,
        transparent 20%, rgba(255, 255, 255, 0.12) 50%, transparent 80%);
}

/* The icon breathes with the sweep, so a still screenshot still reads as "working". */
.f4s-thumb-state.is-working .f4s-thumb-state-icon,
.f4s-thumb-state.is-uploading .f4s-thumb-state-icon {
    animation: f4s-thumb-pulse 1.8s ease-in-out infinite;
}

@keyframes f4s-thumb-sweep {
    from { transform: translateX(-100%); }
    to   { transform: translateX(100%); }
}

@keyframes f4s-thumb-pulse {
    0%, 100% { opacity: 0.55; transform: scale(0.94); }
    50%      { opacity: 1; transform: scale(1.06); }
}

/* Someone who asked for less motion gets the icon without the animation. */
@media (prefers-reduced-motion: reduce) {
    .f4s-thumb-state::after,
    .f4s-thumb-state .f4s-thumb-state-icon {
        animation: none;
    }
}

/* Duration / status chip pinned to a thumbnail corner. */
.f4s-thumb-badge {
    position: absolute;
    right: 0.5rem;
    bottom: 0.5rem;
    padding: 0.1rem 0.4rem;
    border-radius: 0.25rem;
    background: rgba(0, 0, 0, 0.72);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 600;
    line-height: 1.4;
}

/* Play affordance revealed on hover over a thumbnail. */
.f4s-thumb-play {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: 1.75rem;
    background: rgba(0, 0, 0, 0.25);
    opacity: 0;
    transition: opacity 0.15s ease-in-out;
}

.f4s-thumb:hover .f4s-thumb-play {
    opacity: 1;
}

/* --------------------------------------------------------------------------
 * Player
 *
 * The class names here are also used by public/assets/client/js/player.js, which
 * builds overlay messages at runtime, so they must not be renamed.
 * ----------------------------------------------------------------------- */

/* Letterboxed player shell; the <video> keeps its own aspect ratio inside it. The player
   has its own typeface (Inter, loaded by the player partial) whatever the page uses. */
.player-wrap {
    --player-font: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
    font-family: var(--player-font);
    -webkit-font-smoothing: antialiased;
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    background: #000;
    border-radius: var(--falcon-border-radius);
    overflow: hidden;
}

.player-wrap video {
    width: 100%;
    height: 100%;
    display: block;
    accent-color: var(--player-accent, var(--falcon-primary));
}

/* Without native controls the picture itself plays / pauses (player.js). */
.player-no-controls video {
    cursor: pointer;
}

/* Owner's title bar: shown before playback, while paused and on hover. */
.player-title {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2;
    padding: 0.75rem 1rem 1.75rem;
    background: linear-gradient(rgba(0, 0, 0, 0.7), transparent);
    color: #fff;
    font-weight: 600;
    font-size: 0.95rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none;
    border-top: 3px solid var(--player-accent, transparent);
    transition: opacity 0.25s;
}

.player-wrap.is-playing .player-title {
    opacity: 0;
}

.player-wrap.is-playing:hover .player-title {
    opacity: 1;
}

/* Owner's watermark logo in one corner; never catches clicks. */
.player-logo {
    position: absolute;
    z-index: 2;
    max-width: 18%;
    max-height: 14%;
    object-fit: contain;
    opacity: 0.85;
    pointer-events: none;
}

.player-logo-top-left { top: 0.75rem; left: 0.75rem; }
.player-logo-top-right { top: 0.75rem; right: 0.75rem; }
.player-logo-bottom-left { bottom: 3.25rem; left: 0.75rem; }
.player-logo-bottom-right { bottom: 3.25rem; right: 0.75rem; }

/* The title bar takes the top edge: push a top logo below it. */
.player-title:not([hidden]) ~ .player-logo-top-left,
.player-title:not([hidden]) ~ .player-logo-top-right {
    top: 2.9rem;
}

/* Covers the video until playback starts, or to explain why it cannot start. */
.player-state {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 1rem;
    color: #fff;
    text-align: center;
}

.player-state[hidden] {
    display: none;
}

.player-state-title {
    font-weight: 600;
    font-size: 0.95rem;
}

.player-state .small {
    font-size: 0.8rem;
    opacity: 0.75;
}

/* Video.js skin: the player fills the 16:9 shell and takes the owner's accent colour.
   Only the few parts that must match F4S are overridden; the rest is the stock skin. */
.player-wrap .video-js {
    width: 100%;
    height: 100%;
    font-family: var(--player-font);
    font-size: 11px;
}

/* Time and quality: slightly larger, figures of equal width so the numbers do not jiggle. */
.player-wrap .video-js .vjs-time-control,
.player-wrap .video-js .f4s-quality-label,
.player-wrap .video-js .vjs-playback-rate-value {
    font-size: 1.15em;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.player-wrap .video-js .vjs-playback-rate .vjs-playback-rate-value {
    line-height: 2.6;
}

/* Subtitle menu (player.js F4SSubtitleButton): tracks first, then the delay / load-file
   actions under a thin rule; the CC icon takes the accent colour while a track shows. */
.player-wrap .video-js .f4s-subs-button .vjs-menu {
    width: 13em;
    left: -5em;
}

.player-wrap .video-js .f4s-subs-button .vjs-menu-content {
    max-height: 20em;
}

.player-wrap .video-js .vjs-menu li.f4s-sub-first {
    border-top: 1px solid rgba(255, 255, 255, 0.2);
    margin-top: 0.3em;
}

.player-wrap .video-js .vjs-menu li.f4s-sub-action {
    text-transform: none;
    font-size: 1em;
}

.player-wrap .video-js .vjs-menu li.f4s-sub-info {
    opacity: 0.75;
}

.player-wrap .video-js .f4s-subs-button.f4s-subs-active .vjs-icon-placeholder {
    color: var(--player-accent, var(--falcon-primary));
}

/* Subtitle text in the player's typeface (Video.js writes the size inline, not the face). */
.player-wrap .video-js .vjs-text-track-display .vjs-text-track-cue > div {
    font-family: var(--player-font) !important;
    font-weight: 500;
    border-radius: 4px;
    padding: 0.05em 0.35em;
}

/* Rewind / forward 10 s buttons next to play (Video.js SkipBackward / SkipForward). */
.player-wrap .video-js .vjs-skip-backward-10,
.player-wrap .video-js .vjs-skip-forward-10 {
    cursor: pointer;
}

/* Loading: the F4S logo in a dark disc, an accent-coloured arc turning on the disc's edge.
   Used by the overlay before the first frame (player.js showLoading, videos still
   processing) and in place of the stock Video.js buffering spinner.
   The arc is drawn by ::before covering the disc exactly (top/left 0, 100 % box,
   border-box): Video.js gives its spinner's ::before "width: inherit" and a negative
   margin, which left the ring 3 px up and to the left of the logo, so every box value is
   set here. The logo is the transparent "F4S" mark (not the square app icon), so nothing
   square sits inside the round ring. */
.f4s-player-loader,
.player-wrap .video-js .vjs-loading-spinner {
    position: relative;
    box-sizing: border-box;
    width: 76px;
    height: 76px;
    border: 0;
    border-radius: 50%;
    background: rgba(8, 12, 20, 0.72) url('../../brand/logo-mark.png') 50% 52% / 46px auto no-repeat;
    box-shadow: 0 6px 22px rgba(0, 0, 0, 0.45);
    opacity: 1;
}

.f4s-player-loader {
    display: inline-block;
}

/* Video.js keeps showing / hiding its spinner itself (display, visibility and its
   vjs-spinner-show animation while waiting or seeking) and centres it with
   top / left 50 % + translate(-50 %, -50 %): only its look is replaced. */
.player-wrap .video-js .vjs-loading-spinner {
    position: absolute;
    margin: 0;
}

.f4s-player-loader::before,
.player-wrap .video-js .vjs-loading-spinner::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: auto;
    bottom: auto;
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    margin: 0;
    border: 3px solid rgba(255, 255, 255, 0.12);
    border-top-color: var(--player-accent, var(--falcon-primary));
    border-right-color: var(--player-accent, var(--falcon-primary));
    border-radius: 50%;
    opacity: 1;
    animation: f4s-logo-ring 0.8s linear infinite;
}

.player-wrap .video-js .vjs-loading-spinner::after {
    display: none;
}

@keyframes f4s-logo-ring {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .f4s-player-loader::before,
    .player-wrap .video-js .vjs-loading-spinner::before { animation-duration: 2.4s; }
}

.player-wrap .video-js .vjs-play-progress,
.player-wrap .video-js .vjs-volume-level {
    background-color: var(--player-accent, var(--falcon-primary));
}

.player-wrap .video-js .vjs-slider:focus {
    box-shadow: 0 0 0 0.125rem var(--player-accent, var(--falcon-primary));
    text-shadow: none;
}

.player-wrap .video-js .vjs-control-bar {
    background: linear-gradient(transparent, rgba(0, 0, 0, 0.75));
}

/* The stock skin hides the elapsed / total time; F4S shows them, as every video site does. */
.player-wrap .video-js .vjs-time-control {
    display: flex;
    align-items: center;
    padding: 0 0.25rem;
    min-width: 0;
}

.player-wrap .video-js .vjs-time-divider {
    padding: 0;
    min-width: 0.4em;
    text-align: center;
}

.player-wrap .video-js .vjs-remaining-time {
    display: none;
}

/* Quality menu: a control-bar button that lists the renditions of the playlist. The
   current choice is written next to the icon ("Auto · 720p"), as players usually do. */
.player-wrap .video-js .vjs-menu-button.f4s-quality,
.player-wrap .video-js .f4s-quality > .vjs-menu-button {
    width: auto;
    padding: 0 0.5rem;
}

.player-wrap .video-js .f4s-quality .vjs-icon-placeholder {
    display: none;
}

.player-wrap .video-js .f4s-quality-label {
    display: inline-block;
    line-height: 3em;
    font-size: 1em;
    white-space: nowrap;
}

.player-wrap .video-js .f4s-quality .vjs-menu {
    width: 8em;
    left: auto;
    right: 0;
}

.player-wrap .video-js .f4s-quality .vjs-menu-content {
    max-height: 14em;
}

.player-wrap .video-js .vjs-menu li.vjs-selected,
.player-wrap .video-js .vjs-menu li.vjs-selected:focus,
.player-wrap .video-js .vjs-menu li.vjs-selected:hover {
    background-color: var(--player-accent, var(--falcon-primary));
    color: var(--player-accent-text, #fff);
}

/* Seek preview (player.js SeekThumbs): a sprite tile above the progress bar with the time
   under it, placed by script at the pointer. The stock hover time is hidden meanwhile. */
.player-wrap .f4s-seek-thumb {
    position: absolute;
    z-index: 3;
    padding: 2px;
    border-radius: 6px;
    background: rgba(0, 0, 0, 0.8);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
    pointer-events: none;
}

.player-wrap .f4s-seek-thumb-img {
    border-radius: 4px;
    background-repeat: no-repeat;
    background-color: #000;
}

.player-wrap .f4s-seek-thumb-time {
    padding: 2px 0 1px;
    color: #fff;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    text-align: center;
}

.player-wrap .video-js.f4s-has-thumbs .vjs-progress-control .vjs-mouse-display,
.player-wrap .video-js.f4s-has-thumbs .vjs-progress-control .vjs-play-progress .vjs-time-tooltip {
    display: none;
}

/* Video ads (player.js VideoAds, Google IMA): the ad layer covers the picture; the content
   controls step aside while an ad plays so the viewer cannot start the video under it. */
.player-wrap .f4s-ad-layer {
    position: absolute;
    inset: 0;
    z-index: 4;
    background: #000;
}

.player-wrap.f4s-ad-playing .vjs-control-bar,
.player-wrap.f4s-ad-playing .player-title,
.player-wrap.f4s-ad-playing .player-logo {
    display: none !important;
}
/* Big round play button shown before the first play. */
.player-start {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 4.5rem;
    height: 4.5rem;
    border: 0;
    border-radius: 50%;
    background: var(--player-accent, rgba(255, 255, 255, 0.92));
    color: var(--player-accent-text, var(--falcon-primary));
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35);
    cursor: pointer;
    transition: transform 0.15s ease-in-out;
}

.player-start:hover {
    transform: scale(1.06);
}

/* Indeterminate spinner while the video is still being processed. */
.player-state .spinner {
    width: 2rem;
    height: 2rem;
    border: 3px solid rgba(255, 255, 255, 0.25);
    border-top-color: #fff;
    border-radius: 50%;
    animation: f4s-spin 0.8s linear infinite;
}

@keyframes f4s-spin {
    to { transform: rotate(360deg); }
}

/* The embed page has no chrome at all: the player fills the whole viewport. */
.f4s-embed-body {
    margin: 0;
    background: #000;
    overflow: hidden;
}

.f4s-embed-body .player-wrap {
    width: 100vw;
    height: 100vh;
    aspect-ratio: auto;
    border-radius: 0;
}

/* --------------------------------------------------------------------------
 * Uploader
 * ----------------------------------------------------------------------- */

/* Drop zone; .is-dragover is toggled by video-uploader.js while a file hovers. */
.f4s-dropzone {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    padding: 3rem 1.5rem 2.5rem;
    text-align: center;
    cursor: pointer;
    border: 2px dashed rgba(var(--f4s-brand-rgb), 0.45);
    border-radius: 1rem;
    /* A tinted panel, not a white box: the drop target has to read as the main thing on
       the page. The tint sits on the card colour, so it follows the theme. */
    background:
        linear-gradient(180deg, rgba(var(--f4s-brand-rgb), 0.14) 0%, rgba(var(--f4s-brand-rgb), 0.05) 100%),
        var(--falcon-emphasis-bg, #fff);
    transition: border-color 0.15s ease-in-out, background 0.15s ease-in-out,
        box-shadow 0.15s ease-in-out, transform 0.15s ease-in-out;
}

/* The dark theme swallows a light tint, so it gets a stronger one. */
[data-bs-theme="dark"] .f4s-dropzone {
    border-color: rgba(88, 158, 255, 0.5);
    background:
        linear-gradient(180deg, rgba(88, 158, 255, 0.22) 0%, rgba(88, 158, 255, 0.07) 100%),
        var(--falcon-emphasis-bg, #fff);
}

.f4s-dropzone:hover,
.f4s-dropzone:focus-visible {
    border-color: var(--falcon-primary);
    background:
        linear-gradient(180deg, rgba(var(--f4s-brand-rgb), 0.2) 0%, rgba(var(--f4s-brand-rgb), 0.08) 100%),
        var(--falcon-emphasis-bg, #fff);
    box-shadow: 0 0.5rem 1.5rem rgba(var(--f4s-brand-rgb), 0.18);
    transform: translateY(-1px);
}

[data-bs-theme="dark"] .f4s-dropzone:hover,
[data-bs-theme="dark"] .f4s-dropzone:focus-visible {
    background:
        linear-gradient(180deg, rgba(88, 158, 255, 0.3) 0%, rgba(88, 158, 255, 0.1) 100%),
        var(--falcon-emphasis-bg, #fff);
}

/* While a file hovers over the page: a solid ring, so the target is unmistakable. */
.f4s-dropzone.is-dragover {
    border-style: solid;
    border-color: var(--falcon-primary);
    background:
        linear-gradient(180deg, rgba(var(--f4s-brand-rgb), 0.28) 0%, rgba(var(--f4s-brand-rgb), 0.12) 100%),
        var(--falcon-emphasis-bg, #fff);
    box-shadow: 0 0 0 0.25rem rgba(var(--f4s-brand-rgb), 0.2);
}

[data-bs-theme="dark"] .f4s-dropzone.is-dragover {
    background:
        linear-gradient(180deg, rgba(88, 158, 255, 0.38) 0%, rgba(88, 158, 255, 0.14) 100%),
        var(--falcon-emphasis-bg, #fff);
}

/* Card colour on the tinted panel, so the icon reads as a raised disc. */
.f4s-dropzone-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 4rem;
    height: 4rem;
    border-radius: 50%;
    color: var(--falcon-primary);
    background: var(--falcon-emphasis-bg, #fff);
    box-shadow: 0 0 0 0.5rem rgba(var(--f4s-brand-rgb), 0.1);
    transition: transform 0.15s ease-in-out;
}

[data-bs-theme="dark"] .f4s-dropzone-icon {
    color: var(--f4s-brand);
    box-shadow: 0 0 0 0.5rem rgba(88, 158, 255, 0.14);
}

.f4s-dropzone:hover .f4s-dropzone-icon,
.f4s-dropzone.is-dragover .f4s-dropzone-icon {
    transform: translateY(-2px) scale(1.04);
}

.f4s-dropzone-title {
    font-size: 1.125rem;
    font-weight: 600;
    color: var(--falcon-emphasis-color, inherit);
}

.f4s-dropzone-text {
    max-width: 30rem;
    font-size: 0.8rem;
    color: var(--falcon-secondary-color);
}

/* The accepted containers as small chips, easier to scan than a sentence. */
.f4s-dropzone-formats {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.375rem;
    margin-top: 0.25rem;
}

.f4s-dropzone-formats > span {
    padding: 0.125rem 0.5rem;
    border-radius: 999px;
    background: var(--falcon-body-bg);
    border: 1px solid var(--falcon-border-color);
    font-size: 0.7rem;
    letter-spacing: 0.02em;
    color: var(--falcon-secondary-color);
}

.f4s-dropzone-note {
    max-width: 32rem;
    font-size: 0.7rem;
    color: var(--falcon-tertiary-color, var(--falcon-secondary-color));
}

/* The chips sit on the tinted panel: the page colour keeps them readable. */
[data-bs-theme="dark"] .f4s-dropzone-formats > span {
    background: rgba(0, 0, 0, 0.25);
    border-color: rgba(255, 255, 255, 0.12);
}

/* One row per file being uploaded. */
.f4s-upload-item + .f4s-upload-item {
    border-top: 1px solid var(--falcon-border-color);
}

/* --------------------------------------------------------------------------
 * Misc
 * ----------------------------------------------------------------------- */

/* Long ids, hostnames and tokens in tables: keep them on one line and selectable. */
.f4s-mono {
    font-family: var(--falcon-font-monospace);
    font-size: 0.75rem;
    white-space: nowrap;
}

/* Marketing landing: hero band above the fold, a soft primary glow that works in both themes. */
.f4s-hero {
    background:
        radial-gradient(60% 50% at 50% 0%, rgba(var(--f4s-brand-rgb), 0.12) 0%, rgba(var(--f4s-brand-rgb), 0) 100%),
        var(--falcon-body-bg);
}

/* Fluid headline: large on desktop, still two readable lines on a phone. */
.f4s-hero-title {
    font-size: clamp(1.6rem, 1rem + 2.2vw, 2.5rem);
    line-height: 1.15;
    letter-spacing: -0.02em;
}

/* --------------------------------------------------------------------------
 * Admin panel components
 *
 * These have no Falcon equivalent, so they keep their F4S class names (panel.js and
 * several views build them) and are restyled here with Falcon's variables.
 * ----------------------------------------------------------------------- */

/* Key/value detail lists on the "show" pages. */
.kv {
    display: grid;
    grid-template-columns: minmax(120px, max-content) 1fr;
    gap: 0.5rem 1.25rem;
    font-size: 0.8rem;
    margin: 0;
}

.kv dt {
    color: var(--falcon-gray-600);
    font-weight: 500;
}

.kv dd {
    margin: 0;
    min-width: 0;
    overflow-wrap: anywhere;
}

/* Health indicator: a coloured dot followed by a label. */
.health {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.75rem;
}

.health::before {
    content: '';
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: var(--falcon-gray-500);
}

.health-ok::before { background: var(--falcon-success); }
.health-warn::before { background: var(--falcon-warning); }
.health-down::before { background: var(--falcon-danger); animation: f4s-pulse 1.6s infinite; }

/* Standalone dot (queue and server rows). */
.dot {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    display: inline-block;
    background: currentColor;
}

.dot-pulse { animation: f4s-pulse 1.6s infinite; }

@keyframes f4s-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.35; }
}

/* Provisioning / job log console. Line colours are set by panel.js. */
.log {
    background: #0f1623;
    color: #cfd8e6;
    font: 0.75rem/1.55 var(--falcon-font-monospace);
    border-radius: var(--falcon-border-radius);
    padding: 0.875rem;
    max-height: 32rem;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-word;
}

.log-line-ok { color: #5ec489; }
.log-line-failed { color: #ee7b6f; }
.log-line-running { color: #e0b054; }
.log .ts { color: #6f7d95; }
.log .step { color: #9ab2ec; font-weight: 500; }

.log-wrap { position: relative; }
.log-status { position: absolute; top: 0.625rem; right: 0.75rem; }

/* One disk of a storage server: name, usage bar, size. */
.disk-row {
    display: grid;
    grid-template-columns: minmax(80px, 140px) 1fr auto;
    gap: 0.625rem;
    align-items: center;
    font-size: 0.75rem;
    padding: 0.25rem 0;
}

/* Cloudflare nameservers to copy into a registrar. */
.nameservers {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

.nameservers code {
    background: var(--falcon-light);
    border: 1px solid var(--falcon-border-color);
    border-radius: var(--falcon-border-radius);
    padding: 0.375rem 0.625rem;
    font-size: 0.78rem;
}

/* Mini bar chart on the panel dashboard (uploads per day). */
.bars {
    display: flex;
    align-items: flex-end;
    gap: 0.5rem;
    height: 11.5rem;
    padding-top: 1.125rem;
    border-bottom: 1px solid var(--falcon-border-color);
}

.bars-col {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: center;
    gap: 0.375rem;
    height: 100%;
}

.bars-value {
    font: 0.6rem var(--falcon-font-monospace);
    color: var(--falcon-gray-500);
}

.bars-bar {
    width: 100%;
    max-width: 1.625rem;
    border-radius: var(--falcon-border-radius) var(--falcon-border-radius) 0 0;
    background: rgba(var(--f4s-brand-rgb), 0.18); /* --falcon-primary at 18% */
    border-bottom: 2px solid var(--falcon-primary);
    min-height: 2px;
}

.bars-col:last-child .bars-bar { background: var(--falcon-primary); }

.bars-labels {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.bars-labels span {
    flex: 1;
    min-width: 0;
    text-align: center;
    font-size: 0.66rem;
    color: var(--falcon-gray-500);
}

.nowrap { white-space: nowrap; }

/* ==========================================================================
 * Controls: buttons, inputs, selects, checkboxes and switches.
 *
 * One set of design tokens drives every control so they share a height, a radius, a
 * border and a focus ring, and look deliberate in both themes. Falcon exposes its
 * buttons through --falcon-btn-* variables, so buttons are restyled by setting those
 * variables rather than by fighting its selectors. Sizes line up: a default button is
 * exactly as tall as a default input (38 px), and the same holds for -sm (31 px) and
 * -lg (46 px), so a button next to a field in a row or an input group never looks off.
 * ======================================================================== */

:root {
    --f4s-radius: 0.5rem;
    --f4s-radius-sm: 0.4rem;
    --f4s-control-bg: #fff;
    --f4s-control-color: #232e3c;
    --f4s-control-border: #d5dfec;
    --f4s-control-border-hover: #b3c4db;
    --f4s-control-placeholder: #9aa7b8;
    --f4s-control-disabled-bg: #f2f5fa;
    --f4s-control-addon-bg: #f5f8fc;
    --f4s-label-color: #4d5969;
    --f4s-focus-border: var(--f4s-brand);
    --f4s-focus-ring: 0 0 0 0.2rem rgba(var(--f4s-brand-rgb), 0.18);
    --f4s-danger-ring: 0 0 0 0.2rem rgba(230, 55, 87, 0.18);
    --f4s-select-arrow: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%236b7a90' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

[data-bs-theme="dark"] {
    --f4s-control-bg: #0d1928;
    --f4s-control-color: #e3e9f2;
    --f4s-control-border: rgba(255, 255, 255, 0.13);
    --f4s-control-border-hover: rgba(255, 255, 255, 0.24);
    --f4s-control-placeholder: #6c7c92;
    --f4s-control-disabled-bg: rgba(255, 255, 255, 0.03);
    --f4s-control-addon-bg: rgba(255, 255, 255, 0.05);
    --f4s-label-color: #b6c2d3;
    --f4s-focus-border: #4a90ec;
    --f4s-focus-ring: 0 0 0 0.2rem rgba(74, 144, 236, 0.3);
    --f4s-danger-ring: 0 0 0 0.2rem rgba(230, 55, 87, 0.3);
    --f4s-select-arrow: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23a4b1c4' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

/* ---------------------------------------------------------------- buttons */

.btn {
    --falcon-btn-padding-y: 0.5rem;
    --falcon-btn-padding-x: 1rem;
    --falcon-btn-font-size: 0.875rem;
    --falcon-btn-font-weight: 500;
    --falcon-btn-line-height: 1.5;
    --falcon-btn-border-radius: var(--f4s-radius);
    --falcon-btn-box-shadow: none;
    --falcon-btn-disabled-opacity: 0.55;
    /* Icon + label buttons: centred, with a fixed gap instead of stray spaces. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    /* Same height as a field even when the button holds only an icon (no text line). */
    min-height: calc(0.875rem * 1.5 + 1rem + 2px);
    white-space: nowrap;
    box-shadow: none;
    transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out,
        border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

.btn:focus-visible {
    box-shadow: var(--f4s-focus-ring);
}

.btn svg {
    flex: 0 0 auto;
}

.btn-sm {
    --falcon-btn-padding-y: 0.3125rem;
    --falcon-btn-padding-x: 0.75rem;
    --falcon-btn-font-size: 0.8125rem;
    --falcon-btn-border-radius: var(--f4s-radius-sm);
    gap: 0.3rem;
    min-height: calc(0.8125rem * 1.5 + 0.625rem + 2px);
}

.btn-lg {
    --falcon-btn-padding-y: 0.625rem;
    --falcon-btn-padding-x: 1.375rem;
    --falcon-btn-font-size: 1rem;
    --falcon-btn-border-radius: 0.6rem;
    min-height: calc(1rem * 1.5 + 1.25rem + 2px);
}

/* Solid primary and danger: flat fill, darker on hover, darker still when pressed. */
/* The button rests on the deeper teal and lightens to the brand colour under the cursor;
   pressing takes one more step towards the light, so the movement stays in one direction. */
.btn-primary {
    --falcon-btn-color: #fff;
    --falcon-btn-bg: #15979c;
    --falcon-btn-border-color: #15979c;
    --falcon-btn-hover-color: #fff;
    --falcon-btn-hover-bg: var(--f4s-brand);
    --falcon-btn-hover-border-color: var(--f4s-brand);
    --falcon-btn-active-color: #fff;
    --falcon-btn-active-bg: #2ac3c9;
    --falcon-btn-active-border-color: #2ac3c9;
    --falcon-btn-disabled-color: #fff;
    --falcon-btn-disabled-bg: #15979c;
    --falcon-btn-disabled-border-color: #15979c;
}

/* Same movement for the red button: the deeper red at rest, the full red on hover. */
.btn-danger {
    --falcon-btn-color: #fff;
    --falcon-btn-bg: #cc2c4a;
    --falcon-btn-border-color: #cc2c4a;
    --falcon-btn-hover-color: #fff;
    --falcon-btn-hover-bg: #e63757;
    --falcon-btn-hover-border-color: #e63757;
    --falcon-btn-active-color: #fff;
    --falcon-btn-active-bg: #ee5470;
    --falcon-btn-active-border-color: #ee5470;
    --falcon-btn-disabled-color: #fff;
    --falcon-btn-disabled-bg: #cc2c4a;
    --falcon-btn-disabled-border-color: #cc2c4a;
}

.btn-danger:focus-visible {
    box-shadow: var(--f4s-danger-ring);
}

/* Text button: same shape and spacing as the other buttons, no underline, and a light
   tint on hover instead of the browser-classic underlined link. Colour utilities such as
   .text-danger or .text-600 on it still win, so "Remove" / "Cancel" keep their meaning. */
.btn-link {
    --falcon-btn-color: var(--falcon-link-color);
    --falcon-btn-hover-color: var(--falcon-link-hover-color);
    --falcon-btn-active-color: var(--falcon-link-hover-color);
    --falcon-btn-bg: transparent;
    --falcon-btn-border-color: transparent;
    --falcon-btn-hover-bg: rgba(var(--f4s-brand-rgb), 0.1);
    --falcon-btn-hover-border-color: transparent;
    --falcon-btn-active-bg: rgba(var(--f4s-brand-rgb), 0.16);
    --falcon-btn-active-border-color: transparent;
    text-decoration: none;
}

.btn-link:hover,
.btn-link:focus-visible {
    text-decoration: none;
}

[data-bs-theme="dark"] .btn-link {
    --falcon-btn-hover-bg: rgba(255, 255, 255, 0.06);
    --falcon-btn-active-bg: rgba(255, 255, 255, 0.1);
}

/* Soft buttons: bordered, tinted, and filled with the solid colour on hover. */
.btn.btn-falcon-default,
.btn.btn-falcon-primary,
.btn.btn-falcon-danger {
    box-shadow: none;
    border: 1px solid transparent;
}

.btn.btn-falcon-default {
    color: var(--f4s-control-color);
    background-color: var(--f4s-control-bg);
    border-color: var(--f4s-control-border);
}

.btn.btn-falcon-default:hover,
.btn.btn-falcon-default:focus-visible {
    color: var(--f4s-brand);
    background-color: rgba(var(--f4s-brand-rgb), 0.06);
    border-color: #b3c9ea;
}

.btn.btn-falcon-default:active,
.btn.btn-falcon-default.active {
    color: var(--f4s-brand-dark);
    background-color: rgba(var(--f4s-brand-rgb), 0.14);
    border-color: #a3bee8;
}

[data-bs-theme="dark"] .btn.btn-falcon-default {
    background-color: rgba(255, 255, 255, 0.04);
}

[data-bs-theme="dark"] .btn.btn-falcon-default:hover,
[data-bs-theme="dark"] .btn.btn-falcon-default:focus-visible {
    color: #fff;
    background-color: rgba(255, 255, 255, 0.09);
    border-color: rgba(255, 255, 255, 0.26);
}

[data-bs-theme="dark"] .btn.btn-falcon-default:active,
[data-bs-theme="dark"] .btn.btn-falcon-default.active {
    color: #fff;
    background-color: rgba(255, 255, 255, 0.14);
}

.btn.btn-falcon-primary {
    color: var(--f4s-brand);
    background-color: rgba(var(--f4s-brand-rgb), 0.08);
    border-color: rgba(var(--f4s-brand-rgb), 0.25);
}

.btn.btn-falcon-danger {
    color: #e63757;
    background-color: rgba(230, 55, 87, 0.07);
    border-color: rgba(230, 55, 87, 0.25);
}

[data-bs-theme="dark"] .btn.btn-falcon-primary {
    color: var(--f4s-brand);
    background-color: rgba(var(--f4s-brand-rgb), 0.16);
    border-color: rgba(74, 144, 236, 0.38);
}

[data-bs-theme="dark"] .btn.btn-falcon-danger {
    color: #f28b9f;
    background-color: rgba(230, 55, 87, 0.14);
    border-color: rgba(230, 55, 87, 0.38);
}

.btn.btn-falcon-primary:hover,
.btn.btn-falcon-primary:focus-visible,
.btn.btn-falcon-primary:active {
    color: #fff;
    background-color: var(--f4s-brand);
    border-color: var(--f4s-brand);
}

.btn.btn-falcon-danger:hover,
.btn.btn-falcon-danger:focus-visible,
.btn.btn-falcon-danger:active {
    color: #fff;
    background-color: #e63757;
    border-color: #e63757;
}

.btn.btn-falcon-danger:focus-visible {
    box-shadow: var(--f4s-danger-ring);
}

.btn:disabled,
.btn.disabled {
    pointer-events: none;
}

/* ---------------------------------------------------------------- labels and hints */

.form-label {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--f4s-label-color);
    margin-bottom: 0.375rem;
}

.form-text {
    color: var(--f4s-control-placeholder);
    margin-top: 0.3rem;
}

.invalid-feedback {
    font-size: 0.75rem;
    margin-top: 0.3rem;
}

/* ---------------------------------------------------------------- inputs, textareas, selects */

.form-control,
.form-select {
    font-size: 0.875rem;
    line-height: 1.5;
    padding: 0.5rem 0.875rem;
    color: var(--f4s-control-color);
    background-color: var(--f4s-control-bg);
    border: 1px solid var(--f4s-control-border);
    border-radius: var(--f4s-radius);
    box-shadow: none;
    transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, background-color 0.15s ease-in-out;
}

.form-select {
    --falcon-form-select-bg-img: var(--f4s-select-arrow);
    padding-right: 2.5rem;
    background-position: right 0.875rem center;
    background-size: 14px 10px;
    cursor: pointer;
}

.form-control:hover:not(:disabled):not([readonly]),
.form-select:hover:not(:disabled) {
    border-color: var(--f4s-control-border-hover);
}

.form-control:focus,
.form-select:focus {
    color: var(--f4s-control-color);
    background-color: var(--f4s-control-bg);
    border-color: var(--f4s-focus-border);
    box-shadow: var(--f4s-focus-ring);
    outline: 0;
}

.form-control::placeholder {
    color: var(--f4s-control-placeholder);
    opacity: 1;
}

.form-control:disabled,
.form-select:disabled,
.form-control[readonly] {
    color: var(--f4s-control-placeholder);
    background-color: var(--f4s-control-disabled-bg);
    border-color: var(--f4s-control-border);
    box-shadow: none;
    cursor: default;
}

/* Read-only fields that exist to be copied (share link, setup key) stay legible. */
.input-group .form-control[readonly],
textarea.form-control[readonly] {
    color: var(--f4s-control-color);
}

textarea.form-control {
    min-height: 5.5rem;
    resize: vertical;
}

.form-control-sm,
.form-select-sm {
    font-size: 0.8125rem;
    padding: 0.3125rem 0.75rem;
    border-radius: var(--f4s-radius-sm);
    min-height: 0;
}

.form-select-sm {
    padding-right: 2.1rem;
    background-position: right 0.7rem center;
}

.form-control-lg,
.form-select-lg {
    font-size: 1rem;
    padding: 0.625rem 1rem;
    border-radius: 0.6rem;
}

/* Validation: red border and a red focus ring, matching the inline message. */
.form-control.is-invalid,
.form-select.is-invalid {
    border-color: #e63757;
}

.form-control.is-invalid {
    background-image: none;
    padding-right: 0.875rem;
}

.form-select.is-invalid {
    --falcon-form-select-bg-icon: none;
    padding-right: 2.5rem;
}

.form-control.is-invalid:focus,
.form-select.is-invalid:focus {
    border-color: #e63757;
    box-shadow: var(--f4s-danger-ring);
}

/* Browser autofill keeps the theme background instead of a yellow or white block. */
.form-control:-webkit-autofill,
.form-control:-webkit-autofill:hover,
.form-control:-webkit-autofill:focus {
    -webkit-text-fill-color: var(--f4s-control-color);
    box-shadow: 0 0 0 100px var(--f4s-control-bg) inset;
    caret-color: var(--f4s-control-color);
}

/* ---------------------------------------------------------------- input groups */

.input-group-text {
    font-size: 0.875rem;
    color: var(--f4s-label-color);
    background-color: var(--f4s-control-addon-bg);
    border: 1px solid var(--f4s-control-border);
    border-radius: var(--f4s-radius);
}

/* A neutral button inside a group shares the field's border so the pair reads as one. */
.input-group > .btn.btn-falcon-default {
    border-color: var(--f4s-control-border);
}

.input-group > .form-control:focus,
.input-group > .form-select:focus {
    z-index: 5;
}

/* ---------------------------------------------------------------- checkboxes, radios, switches */

.form-check-input {
    width: 1.05rem;
    height: 1.05rem;
    margin-top: 0.2rem;
    background-color: var(--f4s-control-bg);
    border: 1px solid var(--f4s-control-border-hover);
    box-shadow: none;
    cursor: pointer;
}

.form-check-input[type="checkbox"] {
    border-radius: 0.3rem;
}

.form-check-input:checked {
    background-color: var(--f4s-brand);
    border-color: var(--f4s-brand);
}

.form-check-input:focus {
    border-color: var(--f4s-focus-border);
    box-shadow: var(--f4s-focus-ring);
}

.form-check-label {
    font-size: 0.875rem;
    cursor: pointer;
}

.form-switch .form-check-input {
    width: 2.25rem;
    height: 1.25rem;
    margin-top: 0.1rem;
    border-radius: 2rem;
    --falcon-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23b3c4db'/%3e%3c/svg%3e");
}

[data-bs-theme="dark"] .form-switch .form-check-input:not(:checked) {
    --falcon-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%236c7c92'/%3e%3c/svg%3e");
}

.form-switch .form-check-input:checked {
    --falcon-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e");
}

/* ---------------------------------------------------------------- alerts */

/* Falcon keeps the 1rem body size; flash messages read better smaller. */
.alert {
    font-size: 0.8125rem;
    line-height: 1.45;
    padding: 0.625rem 0.875rem;
    border-radius: var(--f4s-radius);
}

.alert-dismissible {
    padding-right: 2.5rem;
}

.alert-dismissible .btn-close {
    padding: 0.8rem 0.875rem;
    font-size: 0.65rem;
}

.alert .alert-heading {
    font-size: 0.875rem;
}

/* ==========================================================================
 * Support tickets: conversation bubbles and the ticket list.
 * ======================================================================== */

.f4s-thread {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
}

/* Requester on the left, support desk on the right, like a chat. */
.f4s-msg {
    max-width: 85%;
    padding: 0.75rem 0.875rem;
    border-radius: 0.75rem;
    border: 1px solid var(--f4s-control-border);
    background: var(--f4s-control-addon-bg);
}

.f4s-msg-requester {
    align-self: flex-start;
    border-top-left-radius: 0.25rem;
}

.f4s-msg-staff {
    align-self: flex-end;
    border-top-right-radius: 0.25rem;
    background: rgba(var(--f4s-brand-rgb), 0.08);
    border-color: rgba(var(--f4s-brand-rgb), 0.25);
}

[data-bs-theme="dark"] .f4s-msg-staff {
    background: rgba(var(--f4s-brand-rgb), 0.14);
    border-color: rgba(74, 144, 236, 0.35);
}

.f4s-msg-head {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    font-size: 0.75rem;
    margin-bottom: 0.3rem;
}

.f4s-msg-body {
    font-size: 0.875rem;
    line-height: 1.55;
    white-space: normal;
    overflow-wrap: anywhere;
}

.f4s-msg-files {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.625rem;
}

.f4s-msg-files img {
    width: 96px;
    height: 72px;
    object-fit: cover;
    border-radius: 0.4rem;
    border: 1px solid var(--f4s-control-border);
    transition: opacity 0.15s ease-in-out;
}

.f4s-msg-files a:hover img {
    opacity: 0.85;
}

@media (max-width: 575.98px) {
    .f4s-msg {
        max-width: 100%;
    }
}

/* Ticket list: the active row uses a tint instead of Bootstrap's solid blue block. */
.f4s-ticket-list .list-group-item {
    background: transparent;
    border-color: var(--f4s-control-border);
    color: inherit;
}

.f4s-ticket-list .list-group-item:hover {
    background: var(--f4s-control-addon-bg);
}

.f4s-ticket-list .list-group-item.active {
    color: inherit;
    background: rgba(var(--f4s-brand-rgb), 0.1);
    border-color: var(--f4s-control-border);
    box-shadow: inset 3px 0 0 var(--f4s-brand);
}

.f4s-ticket-list {
    max-height: 70vh;
    overflow-y: auto;
}

/* ==========================================================================
 * Text size and small screens.
 * ======================================================================== */

/* Falcon keeps the body at 1rem (16px), so any text in a card without a size utility -
   queue names, library names, list rows - rendered noticeably larger than the headings
   and tables around it. Cards and list rows now default to 14px; headings, fs-* utilities,
   buttons and fields set their own size and are unaffected. */
.card,
.list-group-item {
    font-size: 0.875rem;
}

/* Tables on narrow screens: every column wrapped word by word into a tall, broken grid.
   Cells now stay on one line and the table scrolls sideways inside its card instead;
   the row actions keep their buttons side by side. */
@media (max-width: 991.98px) {
    .table-responsive > .table th,
    .table-responsive > .table td {
        white-space: nowrap;
    }

    .table-responsive {
        -webkit-overflow-scrolling: touch;
    }

    .table td.text-end,
    .table td:last-child {
        white-space: nowrap;
    }
}

/* Row actions stay on one line at every width. In a table the last column has no width of
   its own, so the browser shrank it to its widest button and .f4s-actions wrapped: the
   edit / reinstall icons dropped under "Open" (Storage servers, Proxies, Domains…), and a
   button could even break between its icon and its label. The table already scrolls
   sideways inside .table-responsive when the row gets too wide. */
.table .f4s-actions {
    flex-wrap: nowrap;
}

.table td .btn {
    white-space: nowrap;
}

/* Row actions: post_button() renders inline forms; keep a small gap between them. */
.table td form.d-inline-block + form.d-inline-block,
.table td a.btn + form.d-inline-block,
.table td form.d-inline-block + a.btn {
    margin-left: 0.25rem;
}

/* ==========================================================================
 * Panel -> Settings: vertical group menu and a Save bar that stays in reach.
 * ======================================================================== */

@media (min-width: 992px) {
    .border-end-lg {
        border-right: 1px solid var(--f4s-control-border);
    }
}

.f4s-settings-nav {
    gap: 0.25rem;
}

.f4s-settings-nav .nav-link {
    color: var(--f4s-control-color);
    font-size: 0.8125rem;
    padding: 0.6rem 0.75rem;
    border-radius: var(--f4s-radius);
    background: transparent;
}

.f4s-settings-nav .nav-link:hover {
    background: var(--f4s-control-addon-bg);
}

.f4s-settings-nav .nav-link.active {
    color: var(--f4s-brand);
    background: rgba(var(--f4s-brand-rgb), 0.1);
}

[data-bs-theme="dark"] .f4s-settings-nav .nav-link.active {
    color: var(--f4s-brand);
    background: rgba(var(--f4s-brand-rgb), 0.18);
}

.f4s-settings-nav-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.9rem;
    height: 1.9rem;
    flex: 0 0 auto;
    border-radius: 0.45rem;
    background: var(--f4s-control-addon-bg);
    border: 1px solid var(--f4s-control-border);
}

.f4s-settings-nav .nav-link.active .f4s-settings-nav-icon {
    background: var(--f4s-brand);
    border-color: var(--f4s-brand);
    color: #fff;
}

/* Small screens: the menu becomes one scrollable row of tabs above the fields. */
@media (max-width: 991.98px) {
    .f4s-settings-nav {
        flex-wrap: nowrap;
        overflow-x: auto;
        border-bottom: 1px solid var(--f4s-control-border);
    }

    .f4s-settings-nav .nav-link {
        white-space: nowrap;
    }
}

/* The Save bar sticks to the bottom of the screen while a long tab is scrolled. */
.f4s-settings-save {
    position: sticky;
    bottom: 0;
    z-index: 5;
}

.tab-pane fieldset legend {
    font-size: 0.75rem;
}

/* form_switch() draws a top rule for stacked rows; the first row of a framed box has none. */
.rounded-3 > .border-top:first-child {
    border-top: 0 !important;
}

/* Translation under a message on the support desk. */
.f4s-msg-translation {
    margin-top: 0.5rem;
    padding-top: 0.5rem;
    border-top: 1px dashed var(--f4s-control-border);
    font-size: 0.8125rem;
    color: var(--f4s-label-color);
    overflow-wrap: anywhere;
}

/* ==========================================================================
 * List pages: filter tabs, filter toolbar and the table under them.
 *
 * Every list card (Media files, Videos, Users, Audit log, Support tickets) is laid out
 * the same way, top to bottom:
 *
 *   .f4s-tabs     underlined tabs with a count pill (shared/filter-tabs.phtml)
 *   .f4s-toolbar  search box with an icon, selects and switches, then Reset + Search
 *                 pushed to the right by .f4s-toolbar-end
 *   table         with a tinted, small-caps header row
 *   pagination
 * ======================================================================== */

/* ---------------------------------------------------------------- tabs */

.f4s-tabs {
    display: flex;
    gap: 0.25rem;
    padding: 0 0.75rem;
    border-bottom: 1px solid var(--falcon-border-color);
    overflow-x: auto;
    scrollbar-width: none;           /* the row scrolls sideways on phones, without a bar */
}

.f4s-tabs::-webkit-scrollbar {
    display: none;
}

.f4s-tab {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: -1px;             /* the active underline sits on the card's rule */
    padding: 0.8rem 0.6rem 0.7rem;
    border-bottom: 2px solid transparent;
    color: var(--falcon-gray-700);
    font-size: 0.8125rem;
    font-weight: 500;
    white-space: nowrap;
    text-decoration: none;
    transition: color 0.15s, border-color 0.15s;
}

.f4s-tab:hover,
.f4s-tab:focus {
    color: var(--falcon-gray-900);
    text-decoration: none;   /* no underline on hover: only the active tab is underlined */
}

.f4s-tab.is-active {
    color: var(--falcon-primary);
    border-bottom-color: var(--falcon-primary);
    font-weight: 600;
}

/* Count pill: grey by default, primary on the active tab, orange/red when the tab
   holds items that need an admin (tone set by the controller). */
.f4s-tab-count {
    min-width: 1.4rem;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    background: var(--falcon-gray-200);
    color: var(--falcon-gray-700);
    font-size: 0.6875rem;
    font-weight: 600;
    line-height: 1.35;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.f4s-tab.is-active .f4s-tab-count {
    background: rgba(var(--falcon-primary-rgb), 0.14);
    color: var(--falcon-primary);
}

.f4s-tab-count.is-warn,
.f4s-tab.is-active .f4s-tab-count.is-warn {
    background: rgba(var(--falcon-warning-rgb), 0.16);
    color: var(--falcon-warning);
}

.f4s-tab-count.is-danger,
.f4s-tab.is-active .f4s-tab-count.is-danger {
    background: rgba(var(--falcon-danger-rgb), 0.14);
    color: var(--falcon-danger);
}

/* ---------------------------------------------------------------- toolbar */

.f4s-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.625rem;
    padding: 0.75rem 1.25rem;
    border-bottom: 1px solid var(--falcon-border-color);
}

/* A toolbar that closes its card (Support tickets) needs no rule of its own. */
.f4s-toolbar:last-child {
    border-bottom: 0;
}

.f4s-toolbar .form-select {
    width: auto;
    min-width: 9rem;
    max-width: 14rem;
}

.f4s-toolbar-field {
    width: 12rem;
}

.f4s-toolbar .form-switch {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding-left: 0;
}

.f4s-toolbar .form-switch .form-check-input {
    float: none;
    margin: 0;
}

.f4s-toolbar .form-switch .form-check-label {
    margin: 0;                       /* Falcon gives labels a bottom margin that lifts the text */
    line-height: 1.25;
    color: var(--f4s-label-color);
    white-space: nowrap;
    cursor: pointer;
}

/* Reset + the submit button, pushed to the right end of the row. */
.f4s-toolbar-end {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    margin-left: auto;
}

/* Search box: a field with a magnifier drawn inside its left edge. */
.f4s-search {
    position: relative;
    flex: 1 1 15rem;
    max-width: 22rem;
    margin: 0;
}

.f4s-search > svg {
    position: absolute;
    top: 50%;
    left: 0.7rem;
    transform: translateY(-50%);
    color: var(--f4s-control-placeholder);
    pointer-events: none;
}

.f4s-search > .form-control {
    padding-left: 2rem;
}

/* A removable filter that does not live in the form, e.g. "videos of one user". */
.f4s-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.25rem 0.6rem;
    border: 1px solid rgba(var(--falcon-primary-rgb), 0.3);
    border-radius: 999px;
    background: rgba(var(--falcon-primary-rgb), 0.08);
    color: var(--falcon-primary);
    font-size: 0.75rem;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
}

.f4s-chip:hover {
    background: rgba(var(--falcon-primary-rgb), 0.16);
    color: var(--falcon-primary);
}

/* Phones: the search box takes the whole first row, the selects share the next one,
   and Reset / Search sit at the end at full width. */
@media (max-width: 575.98px) {
    .f4s-toolbar {
        padding: 0.75rem 1rem;
    }

    .f4s-search,
    .f4s-toolbar-field {
        flex: 1 1 100%;
        max-width: none;
        width: auto;
    }

    .f4s-toolbar .form-select {
        flex: 1 1 calc(50% - 0.3125rem);
        min-width: 0;
        max-width: none;
    }

    .f4s-toolbar-end {
        flex: 1 1 100%;
        justify-content: flex-end;
    }
}

/* ---------------------------------------------------------------- the table */

/* Header row of a list card: small grey caps on a light tint, so it reads as a legend
   rather than as the first data row; the outer cells line up with the toolbar. */
.card > .table-responsive > .table > thead th {
    padding-top: 0.6rem;
    padding-bottom: 0.6rem;
    background: var(--falcon-tertiary-bg);
    color: var(--falcon-gray-600);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
}

.card > .table-responsive > .table > :not(caption) > tr > :first-child {
    padding-left: 1.25rem;
}

.card > .table-responsive > .table > :not(caption) > tr > :last-child {
    padding-right: 1.25rem;
}

.card > .table-responsive > .table > tbody > tr > td {
    padding-top: 0.6rem;
    padding-bottom: 0.6rem;
    vertical-align: middle;
}

/* The empty-state row spans every column: let its text wrap even where the table cells
   are forced onto one line for sideways scrolling (small screens, see above). */
.card > .table-responsive > .table > tbody > tr > td[colspan] {
    white-space: normal;
}

.card > .table-responsive > .table > tbody > tr:last-child > td {
    border-bottom: 0;
}

.card > .table-responsive > .table-sm > tbody > tr:hover > td {
    background: rgba(var(--falcon-primary-rgb), 0.03);
}

/* ==========================================================================
 * Earnings, settings and analytics (client area).
 * ======================================================================== */

/* Rounded square holding a card's icon, tinted with a Falcon *-subtle background. */
.f4s-card-icon {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 0.6rem;
}

/* ---------------------------------------------------------------- choice cards */

/* A radio button drawn as a card (payout methods, revenue share tiers). The native input
   stays in the DOM for keyboard use and form posting, only visually hidden. */
.f4s-choice-grid {
    display: grid;
    gap: 0.625rem;
}

.f4s-choice-grid-2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 576px) and (max-width: 1199.98px) {
    .f4s-choice-grid-2 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .f4s-choice-grid-2:has(.f4s-choice-tier) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.f4s-choice {
    position: relative;
    display: block;
    margin: 0;
    cursor: pointer;
}

.f4s-choice > input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.f4s-choice-body {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    height: 100%;
    padding: 0.9rem 0.75rem 0.8rem;
    border: 1px solid var(--f4s-control-border);
    border-radius: var(--f4s-radius);
    background: var(--f4s-control-bg);
    text-align: center;
    transition: border-color 0.15s, box-shadow 0.15s, background-color 0.15s;
}

.f4s-choice:hover .f4s-choice-body {
    border-color: var(--f4s-control-border-hover);
}

.f4s-choice > input:focus-visible + .f4s-choice-body {
    box-shadow: var(--f4s-focus-ring);
}

.f4s-choice > input:checked + .f4s-choice-body {
    border-color: var(--falcon-primary);
    background: rgba(var(--falcon-primary-rgb), 0.06);
    box-shadow: 0 0 0 1px var(--falcon-primary);
}

.f4s-choice-title {
    font-weight: 600;
    color: var(--falcon-gray-900);
}

.f4s-choice-sub {
    font-size: 0.6875rem;
    color: var(--falcon-gray-600);
}

.f4s-choice-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.9rem;
    height: 1.9rem;
    margin-bottom: 0.2rem;
    border-radius: 0.5rem;
    background: var(--falcon-gray-200);
    color: var(--falcon-gray-700);
}

/* Tick in the corner of the selected card. */
.f4s-choice-check {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    display: none;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    height: 1.25rem;
    border-radius: 50%;
    background: var(--falcon-primary);
    color: #fff;
}

.f4s-choice > input:checked + .f4s-choice-body .f4s-choice-check {
    display: inline-flex;
}

/* Payout method: a coloured letter badge instead of a third-party logo. */
.f4s-method-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    margin-bottom: 0.25rem;
    border-radius: 0.55rem;
    background: var(--badge);
    color: #fff;
    font-weight: 700;
    font-size: 0.95rem;
}

/* Revenue share tier: big percentage and four progress segments. */
.f4s-tier-pct {
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--falcon-gray-900);
    font-variant-numeric: tabular-nums;
}

.f4s-tier-bars {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.25rem;
    width: 100%;
    margin-top: 0.5rem;
}

.f4s-tier-bars > span {
    height: 4px;
    border-radius: 2px;
    background: var(--falcon-gray-300);
}

.f4s-tier-bars > span.is-on {
    background: var(--falcon-gray-600);
}

.f4s-choice > input:checked + .f4s-choice-body .f4s-tier-bars > span.is-on {
    background: var(--falcon-primary);
}

.f4s-choice > input:checked + .f4s-choice-body .f4s-choice-icon {
    background: rgba(var(--falcon-primary-rgb), 0.14);
    color: var(--falcon-primary);
}

/* A whole-row switch: icon, label + hint, switch on the right; the row is the label. */
.f4s-toggle-tile {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    height: 100%;
    margin: 0;
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--f4s-control-border);
    border-radius: var(--f4s-radius);
    background: var(--f4s-control-bg);
    cursor: pointer;
}

.f4s-toggle-tile:hover {
    border-color: var(--f4s-control-border-hover);
}

.f4s-toggle-tile .form-switch {
    padding-left: 0;
}

.f4s-toggle-tile .form-switch .form-check-input {
    float: none;
    margin: 0;
}

/* ---------------------------------------------------------------- analytics */

/* Segmented control: a row of links, the active one raised (range presets, chart/table). */
.f4s-segmented {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.125rem;
    padding: 0.2rem;
    border-radius: var(--f4s-radius);
    background: var(--falcon-gray-200);
}

.f4s-segmented > a {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.3rem 0.7rem;
    border-radius: var(--f4s-radius-sm);
    color: var(--falcon-gray-700);
    font-size: 0.8125rem;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
}

.f4s-segmented > a:hover {
    color: var(--falcon-gray-900);
    text-decoration: none;
}

.f4s-segmented > a.is-active {
    background: var(--falcon-primary);
    color: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
}

.f4s-chart {
    width: 100%;
    height: 320px;
}

/* Traffic quality score: a ring filled to the score. */
.f4s-score {
    --score: 100;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.4rem;
    height: 3.4rem;
    border-radius: 50%;
    background:
        radial-gradient(closest-side, var(--falcon-card-bg, var(--falcon-body-bg)) 76%, transparent 78% 100%),
        conic-gradient(currentColor calc(var(--score) * 1%), var(--falcon-gray-200) 0);
    font-weight: 700;
    font-size: 1rem;
    font-variant-numeric: tabular-nums;
}

@media (max-width: 575.98px) {
    .f4s-segmented {
        width: 100%;
    }

    .f4s-segmented > a {
        flex: 1 1 auto;
        justify-content: center;
    }
}

/* ---------------------------------------------------------------- settings: video & player */

.f4s-choice-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.f4s-choice-grid-5 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

@media (min-width: 576px) {
    .f4s-choice-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .f4s-choice-grid-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

/* Colour field: the native picker as a swatch glued to the hex input. */
.f4s-color-field {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
    padding: 0.2rem 0.3rem 0.2rem 0.2rem;
    border: 1px solid var(--f4s-control-border);
    border-radius: var(--f4s-radius);
    background: var(--f4s-control-bg);
}

.f4s-color-field input[type="color"] {
    width: 1.9rem;
    height: 1.9rem;
    padding: 0;
    border: 0;
    border-radius: 0.4rem;
    background: none;
    cursor: pointer;
}

.f4s-color-field input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.f4s-color-field input[type="color"]::-webkit-color-swatch { border: 0; border-radius: 0.4rem; }

.f4s-color-field .form-control {
    width: 6rem;
    border: 0;
    box-shadow: none;
    background: transparent;
}

.f4s-swatch {
    width: 1.75rem;
    height: 1.75rem;
    padding: 0;
    border: 2px solid var(--f4s-control-border);
    border-radius: 50%;
    background: var(--swatch);
    cursor: pointer;
    transition: transform 0.12s;
}

.f4s-swatch:hover { transform: scale(1.1); }

.f4s-swatch.is-active {
    border-color: var(--falcon-card-bg, #fff);
    box-shadow: 0 0 0 2px var(--falcon-primary);
}

/* Live preview frame. */
.f4s-preview-box {
    padding: 0.9rem;
    border: 1px solid var(--f4s-control-border);
    border-radius: 0.75rem;
    background: var(--falcon-tertiary-bg);
}

.f4s-live-dot {
    display: inline-block;
    width: 0.5rem;
    height: 0.5rem;
    margin-right: 0.25rem;
    border-radius: 50%;
    background: var(--falcon-success);
}

.f4s-player-preview {
    background: radial-gradient(ellipse at 50% 40%, #1f2a3c, #05080d);
}

.f4s-player-preview .player-start {
    width: 3.4rem;
    height: 3.4rem;
}

.f4s-preview-controls {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 3;
    padding: 1.25rem 0.75rem 0.5rem;
    background: linear-gradient(transparent, rgba(0, 0, 0, 0.75));
    color: #fff;
    font-size: 0.6875rem;
    font-family: var(--falcon-font-monospace, monospace);
}

.f4s-preview-progress {
    height: 3px;
    margin-bottom: 0.4rem;
    border-radius: 2px;
    background: rgba(255, 255, 255, 0.25);
}

.f4s-preview-progress > span {
    display: block;
    width: 38%;
    height: 100%;
    border-radius: 2px;
    background: var(--player-accent);
}

.f4s-preview-quality {
    padding: 0 0.3rem;
    border-radius: 0.2rem;
    background: rgba(255, 255, 255, 0.85);
    color: #111;
    font-weight: 700;
}

.f4s-preview-controls[hidden],
.f4s-player-preview [hidden] {
    display: none !important;
}

/* Layout choice: a miniature of the grid. */
.f4s-grid-icon {
    display: grid;
    grid-template-columns: repeat(var(--cols), 1fr);
    gap: 2px;
    width: 2.6rem;
    height: 1.9rem;
    margin-bottom: 0.3rem;
    padding: 3px;
    border-radius: 0.35rem;
    background: var(--falcon-gray-200);
}

.f4s-grid-icon > span {
    border-radius: 1px;
    background: var(--falcon-gray-500);
}

.f4s-choice > input:checked + .f4s-choice-body .f4s-grid-icon > span {
    background: var(--falcon-primary);
}

/* ---------------------------------------------------------------- my videos: grid layout */

.f4s-video-grid {
    display: grid;
    grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr));
    gap: 1rem;
    padding: 1rem;
}

@media (max-width: 1199.98px) {
    .f4s-video-grid { grid-template-columns: repeat(min(var(--cols, 3), 3), minmax(0, 1fr)); }
}

@media (max-width: 767.98px) {
    .f4s-video-grid { grid-template-columns: repeat(min(var(--cols, 3), 2), minmax(0, 1fr)); }
}

@media (max-width: 419.98px) {
    .f4s-video-grid { grid-template-columns: minmax(0, 1fr); }
}

.f4s-video-tile {
    display: flex;
    flex-direction: column;
    min-width: 0;
    border: 1px solid var(--falcon-border-color);
    border-radius: 0.6rem;
    overflow: hidden;
    background: var(--falcon-card-bg);
}

.f4s-video-tile .f4s-thumb {
    border-radius: 0;
}

/* ---------------------------------------------------------------- settings: custom domains */

/* One numbered step of "Connect a custom domain". */
.f4s-step {
    padding: 1rem;
    border: 1px solid var(--f4s-control-border);
    border-radius: 0.75rem;
    background: var(--falcon-tertiary-bg);
}

.f4s-step-title {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.6rem;
    font-weight: 600;
    font-size: 0.8125rem;
    color: var(--falcon-gray-900);
}

/* A value with a Copy button (nameservers). */
.f4s-copy-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.4rem;
    padding: 0.45rem 0.75rem;
    border: 1px solid var(--f4s-control-border);
    border-radius: var(--f4s-radius);
    background: var(--f4s-control-bg);
    font-size: 0.8125rem;
}

/* Three choices (crypto payout methods): three columns, one per row on very small phones. */
.f4s-choice-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

@media (max-width: 399.98px) {
    .f4s-choice-grid-3 { grid-template-columns: minmax(0, 1fr); }
}

/* ---------------------------------------------------------------- tabs switched in place */

/* Icon inside a tab (Settings, Profile). */
.f4s-tab > svg {
    flex: 0 0 auto;
    opacity: 0.8;
}

/* "On" state pill (two-factor). */
.f4s-tab-count.is-ok,
.f4s-tab.is-active .f4s-tab-count.is-ok {
    background: rgba(var(--falcon-success-rgb), 0.15);
    color: var(--falcon-success);
}

/* A card holding only the tab bar needs no rule under it. */
.card > .f4s-tabs:last-child {
    border-bottom: 0;
}

/* Submit button while a form saves in place (app.js): a small spinner before the label. */
.btn.is-loading {
    position: relative;
    pointer-events: none;
}

.btn.is-loading::before {
    content: "";
    display: inline-block;
    width: 0.8em;
    height: 0.8em;
    margin-right: 0.4em;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    vertical-align: -0.1em;
    animation: f4s-spin 0.7s linear infinite;
}

/* Card header icons stay small so headers keep the admin panel's height. */
.card-header .f4s-card-icon {
    width: 1.8rem;
    height: 1.8rem;
    border-radius: 0.5rem;
}

/* Payout methods: 2 x 2 where the card is half the page (xl+) or on phones, one row of
   four when the card spans the page (tablets and small laptops). */
.f4s-choice-grid-methods { grid-template-columns: repeat(2, minmax(0, 1fr)); }

@media (min-width: 576px) and (max-width: 1199.98px) {
    .f4s-choice-grid-methods { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ==========================================================================
 * My videos: folders, selection and bulk actions (library.js).
 * ======================================================================== */

/* Row of folder chips under the toolbar. */
.f4s-folder-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    padding: 0.65rem 1.25rem;
    border-bottom: 1px solid var(--falcon-border-color);
}

.f4s-folder-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.7rem;
    border: 1px solid var(--f4s-control-border);
    border-radius: 999px;
    background: var(--f4s-control-bg);
    color: var(--falcon-gray-700);
    font-size: 0.8125rem;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
}

.f4s-folder-chip:hover {
    border-color: var(--f4s-control-border-hover);
    color: var(--falcon-gray-900);
    text-decoration: none;
}

.f4s-folder-chip.is-active {
    border-color: var(--falcon-primary);
    background: rgba(var(--falcon-primary-rgb), 0.08);
    color: var(--falcon-primary);
}

.f4s-folder-chip.is-active .f4s-tab-count {
    background: rgba(var(--falcon-primary-rgb), 0.14);
    color: var(--falcon-primary);
}

.f4s-folder-add {
    border-style: dashed;
    color: var(--falcon-gray-600);
}

/* Header of the open folder (name, Rename, Delete folder). */
.f4s-folder-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    padding: 0.65rem 1.25rem;
    border-bottom: 1px solid var(--falcon-border-color);
    background: var(--falcon-tertiary-bg);
}

/* Selection bar: sticks to the top of the viewport while scrolling the list. */
.f4s-bulkbar {
    position: sticky;
    top: 4.2rem;
    z-index: 5;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    padding: 0.55rem 1.25rem;
    border-bottom: 1px solid rgba(var(--falcon-primary-rgb), 0.25);
    background: rgba(var(--falcon-primary-rgb), 0.07);
    backdrop-filter: blur(6px);
}

.f4s-bulkbar[hidden] {
    display: none;
}

.f4s-select-all {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.45rem 1rem;
    border-bottom: 1px solid var(--falcon-border-color);
}

/* Custom checkbox: a rounded square that fills with the primary colour. */
.f4s-check {
    position: relative;
    display: inline-flex;
    flex: 0 0 auto;
    margin: 0;
    cursor: pointer;
}

.f4s-check > input {
    position: absolute;
    opacity: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    cursor: pointer;
}

.f4s-check > span {
    width: 1.1rem;
    height: 1.1rem;
    border: 1.5px solid var(--f4s-control-border-hover);
    border-radius: 0.3rem;
    background: var(--f4s-control-bg);
    transition: background-color 0.12s, border-color 0.12s;
}

.f4s-check > input:checked + span,
.f4s-check > input:indeterminate + span {
    border-color: var(--falcon-primary);
    background: var(--falcon-primary) center / 70% no-repeat url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2.5' d='m3.5 8.5 3 3 6-7'/%3e%3c/svg%3e");
}

.f4s-check > input:indeterminate + span {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath stroke='%23fff' stroke-linecap='round' stroke-width='2.5' d='M4 8h8'/%3e%3c/svg%3e");
}

.f4s-check > input:focus-visible + span {
    box-shadow: var(--f4s-focus-ring);
}

/* Checkbox over a grid tile's thumbnail. */
.f4s-tile-check {
    position: absolute;
    top: 0.45rem;
    left: 0.45rem;
    z-index: 2;
    display: inline-flex;
    padding: 0.2rem;
    border-radius: 0.4rem;
    background: rgba(0, 0, 0, 0.35);
}

/* Selected rows and tiles are tinted. */
.f4s-video-row.is-selected,
.f4s-video-tile.is-selected {
    background: rgba(var(--falcon-primary-rgb), 0.05);
}

.f4s-video-tile.is-selected {
    border-color: var(--falcon-primary);
}

/* "…" menu button of a video. */
.f4s-kebab {
    padding: 0.2rem 0.45rem;
    line-height: 1;
}

.f4s-kebab + .dropdown-menu form {
    margin: 0;
}

.dropdown-item > svg {
    margin-right: 0.35rem;
    vertical-align: -0.15em;
    opacity: 0.75;
}

/* ==========================================================================
 * Landing page: "Your traffic. Your revenue." (#earn)
 * ======================================================================== */

.f4s-earn {
    scroll-margin-top: 4rem;
}

/* Small caps label (also used by the "Maximum rate" style labels elsewhere). */
.f4s-eyebrow {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--falcon-primary);
}

/* Headline card: the best rate on a primary gradient. */
.f4s-earn-hero {
    display: flex;
    flex-direction: column;
    padding: 2rem;
    border-radius: 1rem;
    background:
        radial-gradient(28rem 18rem at 100% 0%, rgba(255, 255, 255, 0.18), transparent 60%),
        linear-gradient(135deg, var(--f4s-brand) 0%, #0f6f73 100%);
    color: #fff;
    box-shadow: 0 18px 40px rgba(var(--f4s-brand-rgb), 0.25);
}

.f4s-earn-hero-label {
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    opacity: 0.85;
}

.f4s-earn-hero-rate {
    margin-top: 0.25rem;
    font-size: clamp(3rem, 7vw, 4.25rem);
    font-weight: 800;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.f4s-earn-hero-unit {
    margin-top: 0.4rem;
    font-size: 0.9375rem;
    opacity: 0.9;
}

.f4s-earn-hero-geos {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin: 1.25rem 0 1.25rem;
}

.f4s-earn-hero-geos > span {
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.16);
    font-size: 0.75rem;
    font-weight: 600;
}

.f4s-earn-hero-points {
    margin: 0 0 1.25rem;
    padding: 0;
    list-style: none;
    font-size: 0.875rem;
}

.f4s-earn-hero-points li {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.2rem 0;
}

.f4s-earn-hero-points svg {
    flex: 0 0 auto;
    padding: 2px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.2);
}

.f4s-earn-hero .btn-light {
    color: #0f6f73;
}

/* One row per country tier: number, countries, rate. */
.f4s-rate-row {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.9rem 1.25rem;
}

.f4s-rate-tier {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    background: var(--falcon-gray-200);
    color: var(--falcon-gray-700);
    font-weight: 700;
    font-size: 0.8125rem;
}

.f4s-rate-tier.is-top {
    background: var(--falcon-primary);
    color: #fff;
}

.f4s-rate-geos {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 0.8125rem;
    line-height: 1.45;
    color: var(--falcon-gray-800, var(--falcon-gray-900));
}

.f4s-rate-price {
    flex: 0 0 auto;
    font-size: 1.25rem;
    font-weight: 800;
    color: var(--falcon-gray-900);
    font-variant-numeric: tabular-nums;
}

/* Analytics: the dates of the chosen period, at the end of the range row. */
.f4s-date-range {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.75rem;
    border-radius: var(--f4s-radius);
    background: var(--falcon-gray-200);
    color: var(--falcon-gray-800, var(--falcon-gray-900));
    font-size: 0.8125rem;
    font-weight: 600;
    white-space: nowrap;
}

/* Segmented control and fields of a toolbar share one height, so a row never looks
   uneven (the search box, selects and buttons are the 31 px "sm" size). */
.f4s-toolbar .f4s-segmented > a {
    min-height: calc(31px - 0.4rem);
}

/* Checkbox column of the admin video list; selected rows are tinted. */
.f4s-col-check {
    width: 2.25rem;
}

.table tr.is-selected > td {
    background: rgba(var(--falcon-primary-rgb), 0.05);
}

/* -------------------------------------------------------------------------
 * Video page /w/{code} (layouts/watch.phtml, watch/show.phtml): a dark, standalone
 * page in the style of the big video hosts - logo bar, player, details, share box.
 * It does not load the Falcon theme, so everything it needs is here.
 * ----------------------------------------------------------------------- */
.f4s-watch-body {
    --w-bg: #0b0f17;
    --w-card: #141a26;
    --w-line: #232b3b;
    --w-text: #e6e9f0;
    --w-muted: #8b93a7;
    --w-accent: #19b1b7;
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--w-bg);
    color: var(--w-text);
    font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
    font-size: 15px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

.f4s-watch-body a { color: var(--w-accent); text-decoration: none; }
.f4s-watch-body a:hover { text-decoration: underline; }
.f4s-watch-body .icon { vertical-align: -2px; }

.f4s-watch-wrap {
    width: 100%;
    max-width: 1100px;
    margin: 0 auto;
    padding: 0 16px;
    box-sizing: border-box;
}

.f4s-watch-header {
    border-bottom: 1px solid var(--w-line);
    background: rgba(11, 15, 23, 0.92);
}

.f4s-watch-header .f4s-watch-wrap {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 56px;
}

.f4s-watch-logo img { display: block; height: 30px; width: auto; }

.f4s-watch-nav { display: flex; align-items: center; gap: 18px; font-size: 14px; }
.f4s-watch-nav a { color: var(--w-muted); }
.f4s-watch-nav a:hover { color: var(--w-text); text-decoration: none; }

.f4s-watch-btn,
.f4s-watch-nav a.f4s-watch-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 14px;
    border-radius: 8px;
    background: var(--w-accent);
    color: #051316;
    font-weight: 600;
    font-size: 14px;
}

.f4s-watch-btn:hover { text-decoration: none; filter: brightness(1.08); }
.f4s-watch-btn.is-ghost { background: transparent; color: var(--w-text); border: 1px solid var(--w-line); font-weight: 500; }
.f4s-watch-btn.is-end { margin-left: auto; }

.f4s-watch-main { flex: 1; padding-top: 20px; padding-bottom: 32px; }

.f4s-watch-player .player-wrap {
    border-radius: 12px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
}

.f4s-watch-note {
    margin-top: 12px;
    padding: 10px 14px;
    border-radius: 10px;
    background: rgba(245, 158, 11, 0.12);
    color: #fbbf24;
    font-size: 13px;
}

.f4s-watch-card {
    margin-top: 16px;
    padding: 18px 20px;
    border: 1px solid var(--w-line);
    border-radius: 12px;
    background: var(--w-card);
}

.f4s-watch-title {
    margin: 0 0 8px;
    font-size: 20px;
    font-weight: 700;
    line-height: 1.35;
    word-break: break-word;
}

.f4s-watch-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 18px;
    color: var(--w-muted);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}

.f4s-watch-badge {
    padding: 1px 8px;
    border-radius: 6px;
    background: rgba(25, 177, 183, 0.15);
    color: var(--w-accent);
    font-weight: 600;
    font-size: 12px;
}

.f4s-watch-badge.is-warn { background: rgba(245, 158, 11, 0.15); color: #fbbf24; }

.f4s-watch-desc {
    margin: 14px 0 0;
    padding-top: 14px;
    border-top: 1px solid var(--w-line);
    color: #c3c8d4;
    font-size: 14px;
    white-space: normal;
    word-break: break-word;
}

.f4s-watch-h2 { margin: 0 0 14px; font-size: 16px; font-weight: 600; }

.f4s-watch-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 14px;
    margin-bottom: 14px;
}

.f4s-watch-options { display: flex; gap: 12px; }

.f4s-watch-label {
    display: block;
    margin-bottom: 6px;
    color: var(--w-muted);
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.f4s-watch-body input[type="text"],
.f4s-watch-body select,
.f4s-watch-body textarea {
    width: 100%;
    box-sizing: border-box;
    padding: 9px 12px;
    border: 1px solid var(--w-line);
    border-radius: 8px;
    background: #0e131d;
    color: var(--w-text);
    font: 13px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

.f4s-watch-body select { font-family: inherit; font-size: 14px; }
.f4s-watch-body textarea { resize: vertical; }

.f4s-watch-field { display: flex; gap: 8px; }
.f4s-watch-field.is-area { align-items: flex-start; }

.f4s-watch-field button {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 9px 14px;
    border: 0;
    border-radius: 8px;
    background: var(--w-accent);
    color: #051316;
    font: 600 13px 'Inter', system-ui, sans-serif;
    cursor: pointer;
    white-space: nowrap;
}

.f4s-watch-field button.is-done { background: #10b981; }

.f4s-watch-footer {
    border-top: 1px solid var(--w-line);
    color: var(--w-muted);
    font-size: 13px;
}

.f4s-watch-footer .f4s-watch-wrap {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 8px 18px;
    padding-top: 16px;
    padding-bottom: 16px;
}

.f4s-watch-footer a { color: var(--w-muted); margin-left: 16px; }

@media (max-width: 640px) {
    .f4s-watch-main { padding-top: 0; }
    .f4s-watch-main.f4s-watch-wrap { padding: 0; }
    .f4s-watch-player .player-wrap { border-radius: 0; }
    .f4s-watch-card, .f4s-watch-note { margin-left: 12px; margin-right: 12px; }
    .f4s-watch-grid { grid-template-columns: minmax(0, 1fr); }
    .f4s-watch-options > div { flex: 1; }
    .f4s-watch-field.is-area { flex-direction: column; align-items: stretch; }
    .f4s-watch-nav span { display: none; }
    .f4s-watch-title { font-size: 17px; }
}

/* My videos -> Edit: the player (poster = thumbnail) at the top of the page, flush with
   its card; before the video is ready the thumbnail is shown dimmed behind the state. */
.f4s-edit-preview .player-wrap {
    border-radius: 0;
}

.f4s-edit-thumb {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0.45;
}

/* Subtitle settings panel of the player (player.js openSubPanel): over the bottom-right of
   the picture, above the control bar, also in full screen. */
.player-wrap .f4s-subpanel {
    position: absolute;
    right: 12px;
    bottom: 3.8em;
    z-index: 6;
    width: 250px;
    max-width: calc(100% - 24px);
    max-height: calc(100% - 5em);
    overflow-y: auto;
    padding: 12px;
    border-radius: 10px;
    background: rgba(12, 16, 24, 0.94);
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.5);
    color: #fff;
    font: 13px/1.4 var(--player-font);
    box-sizing: border-box;
}

.player-wrap .f4s-subpanel[hidden] { display: none; }

.player-wrap .f4s-subpanel-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
    font-size: 14px;
}

.player-wrap .f4s-subpanel-x {
    border: 0;
    background: none;
    color: #fff;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    opacity: 0.8;
}

.player-wrap .f4s-subpanel-label {
    display: block;
    margin: 10px 0 5px;
    color: rgba(255, 255, 255, 0.65);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.player-wrap .f4s-subpanel-hint { text-transform: none; letter-spacing: 0; font-weight: 400; }

.player-wrap .f4s-subpanel-select {
    width: 100%;
    padding: 6px 8px;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 6px;
    background: #1a2130;
    color: #fff;
    font: inherit;
}

.player-wrap .f4s-subpanel button {
    font: inherit;
    cursor: pointer;
}

.player-wrap .f4s-subpanel-upload,
.player-wrap .f4s-subpanel-reset {
    display: block;
    width: 100%;
    margin-top: 8px;
    padding: 7px 10px;
    border: 1px dashed rgba(255, 255, 255, 0.35);
    border-radius: 6px;
    background: transparent;
    color: #fff;
}

.player-wrap .f4s-subpanel-upload:hover { border-color: var(--player-accent, #19b1b7); color: var(--player-accent, #19b1b7); }

.player-wrap .f4s-subpanel-reset {
    border-style: solid;
    border-color: transparent;
    color: rgba(255, 255, 255, 0.7);
    font-size: 12px;
}

.player-wrap .f4s-subpanel-delay {
    display: grid;
    grid-template-columns: auto auto 1fr auto auto;
    align-items: center;
    gap: 4px;
}

.player-wrap .f4s-subpanel-delay button {
    padding: 5px 6px;
    border: 0;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.12);
    color: #fff;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
}

.player-wrap .f4s-subpanel-delay button:hover { background: var(--player-accent, #19b1b7); color: var(--player-accent-text, #fff); }

.player-wrap .f4s-subpanel-delay output {
    text-align: center;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* Settings -> Earnings: the two ad mode cards (Earn / Own ads) side by side. */
.f4s-choice-grid-modes {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
}

.f4s-choice-grid-modes .f4s-choice-body {
    gap: 0.15rem;
    padding: 0.85rem 0.75rem;
}

.f4s-mode-title {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--falcon-gray-900);
    line-height: 1.2;
}

.f4s-choice-grid-modes .f4s-choice-sub {
    white-space: normal;
    word-break: break-word;
}

/* -------------------------------------------------------------------------
 * Realtime card (shared/js/realtime.js): people online now, on the user dashboard and the
 * panel dashboard. A pulsing dot, big counters, 30 one-minute bars and the videos watched.
 * ----------------------------------------------------------------------- */
.f4s-rt-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #10b981;
    box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.6);
    animation: f4s-rt-pulse 2s infinite;
}

[data-realtime].is-stale .f4s-rt-dot { background: #f59e0b; animation: none; }

@keyframes f4s-rt-pulse {
    70% { box-shadow: 0 0 0 8px rgba(16, 185, 129, 0); }
    100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); }
}

.f4s-rt-figure {
    font-size: 2rem;
    font-weight: 700;
    line-height: 1;
    color: var(--falcon-gray-900);
    font-variant-numeric: tabular-nums;
}

.f4s-rt-bars {
    display: flex;
    align-items: flex-end;
    gap: 3px;
    height: 64px;
    padding-top: 4px;
}

.f4s-rt-bar {
    flex: 1 1 0;
    min-width: 2px;
    border-radius: 2px 2px 0 0;
    background: rgba(25, 177, 183, 0.45);
    transition: height 0.4s ease;
}

.f4s-rt-bar.is-now { background: var(--falcon-primary, #19b1b7); }
.f4s-rt-bars.is-members .f4s-rt-bar { background: rgba(139, 92, 246, 0.45); }
.f4s-rt-bars.is-members .f4s-rt-bar.is-now { background: #8b5cf6; }

.f4s-rt-top {
    list-style: none;
    margin: 0;
    padding: 0;
}

.f4s-rt-top li {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.4rem 0;
    border-bottom: 1px solid var(--falcon-border-color, rgba(0, 0, 0, 0.06));
    font-size: 0.8rem;
    min-width: 0;
}

.f4s-rt-top li:last-child { border-bottom: 0; }
.f4s-rt-top a { flex: 1 1 auto; min-width: 0; color: var(--falcon-gray-900); font-weight: 600; }
.f4s-rt-owner { flex: 0 1 30%; min-width: 0; color: var(--falcon-gray-500); }

.f4s-rt-count {
    flex: 0 0 auto;
    min-width: 2.2rem;
    padding: 0.05rem 0.5rem;
    border-radius: 1rem;
    background: rgba(16, 185, 129, 0.12);
    color: #059669;
    font-weight: 700;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.f4s-rt-empty { color: var(--falcon-gray-500); justify-content: center; }

/* "N new jobs since you opened this page" (Panel -> Encode jobs): a rounded bar with air
   between the tabs above and the table below, the text and its button on one line. */
.f4s-new-bar {
    margin: 0.75rem 1rem;
    padding: 0.55rem 0.6rem 0.55rem 1rem;
    border-radius: var(--f4s-radius, 0.5rem);
    font-size: 0.8125rem;
}

.f4s-new-bar:not([hidden]) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 1rem;
}

.f4s-new-bar .btn {
    padding: 0.2rem 0.75rem;
    font-size: 0.75rem;
    white-space: nowrap;
}

/* Upload page: "Upload to folder" bar above both tabs. */
.f4s-upload-folder .form-select {
    width: auto;
    min-width: 14rem;
    max-width: 100%;
}
