/*
 * theme-qrfile.css — QRFile brand skin for PairDrop.
 *
 * Loaded LAST, after styles-main.css and styles-deferred.css, so it can override
 * upstream without touching upstream files. Everything QRFile-specific lives here.
 *
 * Design language lifted from get.qrfile.ru: editorial brutalism — hairline black
 * rules dividing the page into cells, Bebas Neue set large and tight, flat blocks
 * of rose, zero curvature, hard offset shadows instead of soft blurs.
 */

/* ------------------------------------------------------------------ *
 * 1. Fonts (self-hosted — the PWA must render correctly offline)
 * ------------------------------------------------------------------ */

@font-face {
    font-family: "Bebas Neue";
    src: url("../fonts/BebasNeue-Regular.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Encode Sans";
    src: url("../fonts/EncodeSans-Regular.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Encode Sans";
    src: url("../fonts/EncodeSans-Medium.woff2") format("woff2");
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Encode Sans";
    src: url("../fonts/EncodeSans-SemiBold.woff2") format("woff2");
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Encode Sans";
    src: url("../fonts/EncodeSans-Bold.woff2") format("woff2");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

/* ------------------------------------------------------------------ *
 * 2. Brand tokens
 * ------------------------------------------------------------------ */

:root {
    --qf-ink: #000000;
    --qf-paper: #f5f5f5;
    --qf-cream: #f8e9c9;
    --qf-rose: #c43d72;
    --qf-rose-mark: #cb4179;
    --qf-orange: #ee7140;
    --qf-violet: #A077F3;
    --qf-blue: #0693e3;

    --qf-display: "Bebas Neue", "Encode Sans", sans-serif;
    --qf-body: "Encode Sans", -apple-system, BlinkMacSystemFont, sans-serif;

    /* The hairline rule that builds the QRFile grid. */
    --qf-rule: 1px;
    --qf-rule-strong: 2px;
}

/* ------------------------------------------------------------------ *
 * 3. Palette override
 *
 * Upstream keeps every colour in custom properties on `body`, and consumes
 * --text-color / --bg-color as bare `r,g,b` triplets inside rgb(). Keep that
 * contract exactly — emitting a hex here would break every rgba() in upstream.
 * ------------------------------------------------------------------ */

body {
    /* Peer badge colours, all drawn from the QRFile site palette. */
    --primary-color: var(--qf-rose);
    --paired-device-color: var(--qf-orange);
    --public-room-color: var(--qf-violet);
    --accent-color: var(--qf-rose);
    --ws-peer-color: var(--qf-blue);
    --btn-disabled-color: #9a9a9a;

    /* Light theme — ink on paper. */
    --lt-text-color: 0, 0, 0;
    --lt-dialog-bg-color: #ffffff;
    --lt-bg-color: 245, 245, 245;
    --lt-bg-color-secondary: #f8e9c9;
    --lt-border-color: #000000;
    --lt-badge-color: #000000;
    --lt-lang-hr-color: #000000;

    --lt-shadow-color-secondary-rgb: 0, 0, 0;
    --lt-shadow-color-secondary-cover-rgb: 248, 233, 201;
    --lt-shadow-color-dialog-rgb: 0, 0, 0;
    --lt-shadow-color-dialog-cover-rgb: 245, 245, 245;

    /* Dark theme — QRFile's site is light-only, so this is an invented but
       brand-consistent inversion: cream on ink, same rose and orange accents. */
    --dt-text-color: 248, 233, 201;
    --dt-dialog-bg-color: #0d0d0d;
    --dt-bg-color: 0, 0, 0;
    --dt-bg-color-secondary: #141414;
    --dt-border-color: #f8e9c9;
    /* Upstream sets `.badge { color: white }` unconditionally, so --badge-color
       is a BACKGROUND that must stay dark enough for white type. Cream here
       would render the display-name badge white-on-cream. */
    --dt-badge-color: #4a4336;
    --dt-lang-hr-color: #3a352b;

    --dt-shadow-color-secondary-rgb: 248, 233, 201;
    --dt-shadow-color-secondary-cover-rgb: 20, 20, 20;
    --dt-shadow-color-dialog-rgb: 248, 233, 201;
    --dt-shadow-color-dialog-cover-rgb: 0, 0, 0;
}

/* ------------------------------------------------------------------ *
 * 4. Typography
 * ------------------------------------------------------------------ */

body,
.btn,
.textarea,
input,
select,
textarea {
    font-family: var(--qf-body);
}

h1,
h2,
h3,
h4,
.dialog-title,
.font-subheading,
x-about .title-wrapper h1 {
    font-family: var(--qf-display);
    font-weight: 400;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    line-height: 1.05;
}

h1 {
    font-size: min(max(2.75rem, 6vw), 4.5rem);
}

h2,
.dialog-title {
    font-size: min(max(1.75rem, 3.6vw), 2.75rem);
}

x-no-peers h2 {
    margin-bottom: 0.35em;
}

/* Bebas has a small x-height and no lowercase; subheadings set in it need air. */
.font-subheading {
    font-size: 1.15rem;
    letter-spacing: 0.06em;
    opacity: 0.85;
}

/* ------------------------------------------------------------------ *
 * 5. Square everything
 *
 * QRFile has no curves anywhere except the logo mark itself. Upstream sets
 * radii on a known, enumerated set of selectors — override exactly those
 * rather than a blanket `* { border-radius: 0 }`, which would also flatten
 * the circular peer ripple and the toggle knobs into unreadable shapes.
 * ------------------------------------------------------------------ */

.panel.column,
.panel.row,
.badge,
#display-name,
.btn-rounded,
.btn-small.btn-rounded,
x-toast,
.textarea,
.highlight,
x-dialog x-paper,
.hr-note > div > span,
.shr-panel .thumb > div,
x-peer .icon-wrapper,
#theme-wrapper:hover::before {
    border-radius: 0;
}

/* The peer avatar becomes a bordered cell — the core QRFile grid motif. */
x-peer .icon-wrapper {
    border: var(--qf-rule-strong) solid var(--border-color);
}

/* ------------------------------------------------------------------ *
 * 6. Buttons — Bebas, uppercase, hard border, invert on hover
 * ------------------------------------------------------------------ */

.btn {
    font-family: var(--qf-display);
    font-size: 1.15rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    border: var(--qf-rule-strong) solid var(--border-color);
    background-color: transparent;
    color: rgb(var(--text-color));
    transition: background-color 120ms ease, color 120ms ease;
}

.btn:hover,
.btn:focus-visible {
    background-color: var(--qf-rose);
    border-color: var(--qf-rose);
    color: #ffffff;
}

.btn.btn-dark,
.btn.text-white {
    background-color: var(--qf-rose);
    border-color: var(--qf-rose);
    color: #ffffff;
}

.btn.btn-dark:hover,
.btn.text-white:hover {
    background-color: var(--qf-ink);
    border-color: var(--qf-ink);
    color: var(--qf-cream);
}

.btn[disabled],
.btn.disabled {
    border-color: var(--btn-disabled-color);
    color: var(--btn-disabled-color);
    background-color: transparent;
}

/* .btn-round is the circular floating action; keep it circular but give it
   the same hard border so it reads as part of the system. */
.btn-round {
    border: var(--qf-rule-strong) solid var(--border-color);
}

/* ------------------------------------------------------------------ *
 * 7. Surfaces — hard offset shadow instead of soft blur
 * ------------------------------------------------------------------ */

x-dialog x-paper {
    border: var(--qf-rule-strong) solid var(--border-color);
    box-shadow: 8px 8px 0 var(--border-color);
}

.panel.column,
.panel.row,
.discovery-wrapper {
    border: var(--qf-rule) solid var(--border-color);
    box-shadow: none;
}

x-toast {
    border: var(--qf-rule-strong) solid var(--qf-cream);
    box-shadow: 5px 5px 0 rgba(0, 0, 0, 0.35);
}

.badge {
    border: var(--qf-rule) solid var(--badge-color);
    font-family: var(--qf-display);
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

#display-name {
    border-bottom: var(--qf-rule-strong) solid var(--border-color);
    font-family: var(--qf-display);
    letter-spacing: 0.05em;
}

.textarea {
    border: var(--qf-rule) solid var(--border-color);
}

/* ------------------------------------------------------------------ *
 * 8. Header / footer chrome
 * ------------------------------------------------------------------ */

header {
    border-bottom: var(--qf-rule) solid var(--border-color);
}

footer {
    border-top: var(--qf-rule) solid var(--border-color);
}

/* The QRFile wordmark sitting in the footer, in place of upstream's
   wifi-tethering glyph. */
.qf-wordmark {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 6px;
}

.qf-wordmark img {
    width: 34px;
    height: 34px;
    display: block;
}

.qf-wordmark .qf-wordmark-text {
    font-family: var(--qf-display);
    font-size: 1.9rem;
    line-height: 1;
    letter-spacing: 0.04em;
    color: var(--qf-rose);
}

.qf-wordmark .qf-wordmark-sub {
    font-family: var(--qf-display);
    font-size: 1.9rem;
    line-height: 1;
    letter-spacing: 0.04em;
    color: rgb(var(--text-color));
}

/* Legal / attribution strip at the very bottom of the About panel. */
.qf-colophon {
    font-family: var(--qf-body);
    font-size: 0.72rem;
    line-height: 1.6;
    text-align: center;
    max-width: 46ch;
    margin: 1.5rem auto 0;
    color: var(--qf-cream);
    opacity: 0.85;
    text-transform: none;
    letter-spacing: 0;
}

.qf-colophon a {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.qf-colophon a:hover {
    color: #ffffff;
}

/* --border-color is ink in the light theme, which would vanish against the
   About panel's dark wash. Rule it in cream instead. */
.qf-colophon .qf-colophon-rule {
    border: 0;
    border-top: var(--qf-rule) solid var(--qf-cream);
    margin: 0 0 0.9rem;
    opacity: 0.4;
}

/* About panel logo — the real QRFile mark, not the tethering glyph. */
x-about .qf-about-mark {
    width: 96px;
    height: 96px;
    display: block;
}

/* The About panel sits on a rose-to-black radial wash (upstream draws it from
   --primary-color), so brand-rose type would be rose-on-rose. Set it in cream. */
x-about .title-wrapper h1 {
    color: var(--qf-cream);
}

x-about .font-subheading {
    color: var(--qf-cream);
    opacity: 0.95;
}

/* ------------------------------------------------------------------ *
 * 9. Accents and details
 * ------------------------------------------------------------------ */

::-moz-selection,
::selection {
    color: #ffffff;
    background: var(--qf-rose);
}

::-webkit-scrollbar-thumb {
    background: var(--qf-rose);
    border-radius: 0;
}

/* The drop-zone instruction frame — a ruled cell, like the site's columns. */
x-instructions:before {
    letter-spacing: 0.02em;
}

/* x-no-peers is a full-height flex container, so a border on it frames the whole
   viewport rather than the message. Leave it unframed — the radar already owns
   this space — and only rule the drop target, which is genuinely a cell. */
x-instructions[drop-bg],
x-instructions[drop-peer] {
    outline: var(--qf-rule-strong) dashed var(--qf-rose);
    outline-offset: 6px;
}

/* Websocket-fallback notice. The underline upstream puts on the second span is
   deliberate — it colour-matches --ws-peer-color so the phrase "routed through
   the server" ties to the badge shown on relayed peers. Keep it; only settle
   the type down so it does not compete with the heading. */
#websocket-fallback {
    font-size: 0.8rem;
    letter-spacing: 0.01em;
}

/* Upstream tints the icon-button hover puck with currentColor; keep it square
   so it matches the rest of the chrome. */
.icon-button:before {
    border-radius: 0;
}

.icon-button:hover,
.icon-button:focus-visible {
    color: var(--qf-rose);
}

/* NOTE: the radar rings are painted on <canvas>, not built from DOM nodes, so
   their colour is set in scripts/ui-main.js (see scripts/render-overlay.py),
   not here. */

/* Language dialog separators. */
.hr-note > div > span {
    border: var(--qf-rule) solid var(--border-color);
    font-family: var(--qf-display);
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

/* ------------------------------------------------------------------ *
 * 10. Motion — one restrained entrance, in keeping with the editorial tone
 * ------------------------------------------------------------------ */

@media (prefers-reduced-motion: no-preference) {
    header,
    footer {
        animation: qf-rule-in 520ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
    }

    footer {
        animation-delay: 90ms;
    }
}

@keyframes qf-rule-in {
    from {
        opacity: 0;
        transform: translateY(-4px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

/* ------------------------------------------------------------------ *
 * 11. Usability layer (see scripts/qf-enhance.js)
 *
 * Stock PairDrop hides its primary actions as unlabelled header icons and
 * shows an empty radar with nothing to click. These styles present the
 * actions in the main column and turn the empty state into a lesson,
 * using the same hairline-ruled cells as get.qrfile.ru.
 * ------------------------------------------------------------------ */

.qf-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
    padding: 0 1rem 1.1rem;
    width: 100%;
    box-sizing: border-box;
}

.qf-action {
    font-family: var(--qf-display);
    font-size: 1.15rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    line-height: 1;
    padding: 0.72em 1.6em;
    border: var(--qf-rule-strong) solid var(--border-color);
    border-radius: 0;
    background: transparent;
    color: rgb(var(--text-color));
    cursor: pointer;
    transition: background-color 120ms ease, color 120ms ease, transform 120ms ease;
}

.qf-action:hover,
.qf-action:focus-visible {
    background: var(--qf-rose);
    border-color: var(--qf-rose);
    color: #ffffff;
}

.qf-action:active {
    transform: translateY(1px);
}

/* The one thing most people came here to do. */
.qf-action-primary {
    background: var(--qf-rose);
    border-color: var(--qf-rose);
    color: #ffffff;
}

.qf-action-primary:hover,
.qf-action-primary:focus-visible {
    background: var(--qf-ink);
    border-color: var(--qf-ink);
    color: var(--qf-cream);
}

/* --- teaching empty state ---------------------------------------- */

.qf-guide {
    width: min(940px, 100%);
    margin: 1.6rem auto 0;
    padding: 0 1rem;
    box-sizing: border-box;
    text-align: left;
}

.qf-guide-title {
    font-family: var(--qf-display);
    font-size: 1.5rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    margin: 0 0 0.7rem;
    padding-bottom: 0.45rem;
    border-bottom: var(--qf-rule) solid var(--border-color);
    opacity: 0.9;
}

.qf-steps {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0;
    list-style: none;
    margin: 0;
    padding: 0;
    /* One shared grid of hairlines, like the columns on get.qrfile.ru. */
    border: var(--qf-rule) solid var(--border-color);
}

.qf-steps > li {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    padding: 1rem 1.05rem;
    font-size: 0.95rem;
    line-height: 1.45;
}

.qf-steps > li + li {
    border-left: var(--qf-rule) solid var(--border-color);
}

.qf-step-n {
    font-family: var(--qf-display);
    font-size: 1.7rem;
    line-height: 1;
    color: var(--qf-rose);
    flex: 0 0 auto;
}

.qf-step-t b {
    font-weight: 600;
    white-space: nowrap;
}

.qf-privacy {
    margin: 0.75rem 0 0;
    font-size: 0.8rem;
    line-height: 1.5;
    opacity: 0.7;
}

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

    .qf-steps > li + li {
        border-left: 0;
        border-top: var(--qf-rule) solid var(--border-color);
    }

    .qf-action {
        font-size: 1.05rem;
        padding: 0.7em 1.15em;
    }

    .qf-guide {
        margin-top: 1.1rem;
    }
}

/* On short viewports the guide would push the footer off-screen; the action
   bar alone is enough to get someone unstuck there. */
@media (max-height: 620px) {
    .qf-guide {
        display: none;
    }
}

/* Empty state, guided variant.
 *
 * Upstream fixes x-no-peers at 137px and fills it with a headline plus a
 * subtitle that restate "open it on another device" and "pair or join a room"
 * — exactly steps 1 and 3 of the guide. Showing both says everything twice and
 * gives the user two competing focal points, so the guide takes over here.
 * The `[drop-bg] *` rule upstream uses to blank this region during a drag still
 * applies, so the drag affordance is unaffected. */
x-no-peers.qf-guided {
    height: auto;
    padding-top: 0;
}

x-no-peers.qf-guided > h2,
x-no-peers.qf-guided > div:not(#qf-guide) {
    display: none;
}

x-no-peers.qf-guided .qf-guide {
    margin-top: 0;
}

x-no-peers.qf-guided .qf-guide-title {
    font-size: min(max(1.9rem, 3.4vw), 2.6rem);
    color: var(--qf-rose);
    opacity: 1;
}

/* Upstream lets this notice run to the viewport edge on narrow screens. */
#websocket-fallback {
    padding: 0 1rem;
    box-sizing: border-box;
}
