/* Get-a-quote page design layer.
 *
 * The presentation layer for Components/Pages/GetAQuotePage.razor. Global CSS,
 * linked from App.razor, so the same three rules pages/book-demo.css and
 * pages/talk-to-sales.css set out apply here:
 *
 * 1. Nothing confines these rules to this page, so every selector is qgq-
 *    prefixed or a descendant of one.
 * 2. @keyframes names are global too — hence qgq- on them, so they cannot
 *    collide with the compiled Tailwind bundle, Home's qh- animations, the demo
 *    page's qbd- ones, the sales page's qts- ones or the trial page's qft- ones.
 * 3. These rules are unlayered and Tailwind v4's utilities live inside @layer,
 *    so they win regardless of specificity. Every selector stays class-based and
 *    prefixed — a bare element selector at the top level here would leak.
 *
 * WHY HAND-WRITTEN CSS AND NOT UTILITIES. The Tailwind bundle in wwwroot is a
 * Next.js build artefact containing only the utilities that build emitted, so a
 * class this page invents does not exist at runtime and an arbitrary value like
 * grid-cols-[1fr_372px] renders as nothing. The previous version of this page
 * carried a comment about exactly that trap and worked around it with
 * grid-cols-3 + col-span-2; owning the CSS removes the constraint.
 *
 * THIRD SIBLING, NOT CLONE. /book-qhrm-demo and /talk-to-sales are the other two
 * conversion flows and all three are deliberately built from the same parts —
 * same violet field, same overlap, same card language — but the texture differs:
 * a plotted dot matrix here against the demo page's square mesh and the sales
 * page's diagonal weave, because this page is about figures being worked out.
 *
 * WHAT THIS FILE DOES NOT STYLE. <SignupFlow /> renders on six other routes, so
 * every rule that reaches into it is a descendant of .qgq-form and touches
 * nothing on those routes.
 *
 * Colour. The site ramp only: #4f46e5 → #7c3aed → #a22dea over the dark violet
 * field #221049 → #140f33. Amber (#f59e0b) is the one hue from outside it and
 * carries a single meaning — "a number you can read right now, without asking" —
 * which is why it appears on the published-pricing routes and nowhere else.
 */

.qgq-page {
    position: relative;
    background: #fff;
}

/* ── hero ───────────────────────────────────────────────────────────── */
/* The tall lower padding is structural, not decorative: .qgq-main pulls itself
   up into it so the form card overlaps the dark field. */
.qgq-hero {
    position: relative;
    overflow: hidden;
    padding: 66px 0 158px;
    background:
        radial-gradient(ellipse 88% 60% at 22% 0%, #3a1c7d 0%, transparent 58%),
        linear-gradient(158deg, #221049 0%, #1a1240 46%, #140f33 100%);
}

.qgq-glow,
.qgq-plot {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.qgq-glow i {
    position: absolute;
    display: block;
    border-radius: 50%;
    filter: blur(108px);
    opacity: .8;
    animation: qgq-drift 34s ease-in-out infinite;
}

.qgq-glow i:nth-child(1) {
    width: 640px;
    height: 640px;
    top: -300px;
    left: -170px;
    background: radial-gradient(circle, rgba(124, 58, 237, .55), transparent 62%);
}

.qgq-glow i:nth-child(2) {
    width: 600px;
    height: 600px;
    bottom: -330px;
    right: -150px;
    animation-delay: -13s;
    background: radial-gradient(circle, rgba(162, 45, 234, .46), transparent 62%);
}

.qgq-glow i:nth-child(3) {
    width: 420px;
    height: 420px;
    top: 24%;
    right: 28%;
    animation-delay: -23s;
    background: radial-gradient(circle, rgba(79, 70, 229, .38), transparent 64%);
}

@keyframes qgq-drift {
    0%, 100% { transform: translate(0, 0) scale(1); }
    36%      { transform: translate(-38px, 30px) scale(1.06); }
    68%      { transform: translate(34px, -28px) scale(.95); }
}

/* A plotted dot matrix over a faint rule grid — same family as the demo page's
   mesh and the sales page's weave, different texture: this is the page where a
   figure gets worked out, so the field reads as graph paper rather than fabric.
   The dots sit on the rule intersections (both are on the same 46px pitch, the
   dots offset by half a cell), which is what keeps it from looking like noise. */
.qgq-plot {
    opacity: .55;
    background-image:
        radial-gradient(circle at center, rgba(255, 255, 255, .16) 0 1.4px, transparent 1.6px),
        repeating-linear-gradient(90deg, rgba(255, 255, 255, .05) 0 1px, transparent 1px 46px),
        repeating-linear-gradient(0deg, rgba(255, 255, 255, .04) 0 1px, transparent 1px 46px);
    background-size: 46px 46px, auto, auto;
    background-position: 23px 23px, 0 0, 0 0;
    -webkit-mask-image: radial-gradient(ellipse 76% 74% at 74% 14%, #000, transparent 76%);
    mask-image: radial-gradient(ellipse 76% 74% at 74% 14%, #000, transparent 76%);
}

.qgq-hero__in {
    position: relative;
    z-index: 5;
}

.qgq-hero__title {
    font-size: clamp(31px, 4vw, 53px);
    line-height: 1.06;
    letter-spacing: -.035em;
    font-weight: 800;
    color: #fff;
    margin: 0 0 22px;
    max-width: 720px;
}

.qgq-hero__lede {
    font-size: clamp(15.5px, 1.2vw, 18px);
    line-height: 1.72;
    color: rgba(255, 255, 255, .8);
    margin: 0 0 30px;
    max-width: 680px;
}

.qgq-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* The leading mark is a pseudo-element, not an icon: these three chips state
   three unrelated facts, so any glyph specific enough to be meaningful would be
   wrong on two of them. */
.qgq-chip {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 9px 18px;
    border-radius: 999px;
    font-size: 13.5px;
    font-weight: 650;
    color: #fff;
    background: rgba(255, 255, 255, .08);
    border: 1px solid rgba(255, 255, 255, .18);
    backdrop-filter: blur(6px);
}

.qgq-chip::before {
    content: "";
    width: 7px;
    height: 7px;
    flex: 0 0 auto;
    border-radius: 99px;
    background: linear-gradient(135deg, #c4b5fd, #a22dea);
    box-shadow: 0 0 0 4px rgba(162, 45, 234, .22);
}

/* ── layout ─────────────────────────────────────────────────────────── */
/* Rides up over the hero's lower edge so the form reads as the point of the
   page rather than as the section after it. Deliberately no background of its
   own — a fade-to-white gradient here would be keyed to this element's height,
   which is the signup form's height, and would smear violet down the white
   page. */
.qgq-main {
    position: relative;
    z-index: 6;
    margin-top: -100px;
    padding-bottom: 92px;
}

.qgq-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 372px;
    gap: 32px;
    align-items: start;
}

/* ── form card ──────────────────────────────────────────────────────── */
/* A gradient hairline rather than a border: the card's top half sits on the
   dark violet field, where a flat 1px slate line disappears. */
.qgq-formcard {
    position: relative;
    padding: 1.5px;
    border-radius: 28px;
    background: linear-gradient(155deg, rgba(255, 255, 255, .62), rgba(124, 58, 237, .5) 48%, rgba(79, 70, 229, .42));
    box-shadow: 0 54px 108px -48px rgba(0, 0, 0, .8), 0 12px 32px -20px rgba(15, 23, 42, .45);
}

.qgq-formcard__in {
    position: relative;
    overflow: hidden;
    padding: 34px 34px 30px;
    border-radius: 26.5px;
    background: linear-gradient(172deg, #fff 0%, #fdfcff 58%, #f9f6ff 100%);
}

.qgq-formcard__in::before {
    content: "";
    position: absolute;
    width: 340px;
    height: 340px;
    top: -230px;
    right: -120px;
    border-radius: 50%;
    pointer-events: none;
    background: radial-gradient(circle, rgba(124, 58, 237, .15), transparent 66%);
}

/* Lifts the flow above ::before — a positioned pseudo-element paints over
   non-positioned content in the same stacking context, so without this the
   corner glow tints the first two fields. */
.qgq-form {
    position: relative;
    z-index: 1;
}

/* ── the form itself ────────────────────────────────────────────────── */
/* <SignupFlow /> renders on seven routes and owns its own markup, so every rule
   below is a descendant of .qgq-form and reaches nothing on the other six.
 *
 * Two consequences of styling another component's DOM from outside, both
 * deliberate:
 *
 * 1. Selectors lean on structure (label > span:first-child) and on stable
 *    semantics (role="alert", type="checkbox", maxlength) rather than on the
 *    flow's utility class strings, which are an implementation detail. The
 *    exceptions are commented where they occur.
 * 2. These rules are unlayered and Tailwind's utilities are layered, so they win
 *    without !important — which also means a utility the flow relies on can be
 *    overridden by accident. The dial-code input is reset back explicitly below
 *    for exactly that reason.
 *
 * Two of the classes the flow asks for have no rule in the prebuilt bundle at
 * all — tracking-[0.5em] on the verification code and bg-indigo-50/70 on the
 * explainer — so the spaced code digits and the tinted explainer panel below are
 * restoring intent, not overriding it. */

/* Fields. One shape for every control: the grid mixes inputs, a select and a
   textarea, and they have to read as one column. */
.qgq-form input:not([type="checkbox"]),
.qgq-form select,
.qgq-form textarea {
    width: 100%;
    padding: 12px 15px;
    border-radius: 13px;
    border: 1px solid #e6e3f5;
    background: #fbfaff;
    color: #0b1020;
    font-size: 14.5px;
    line-height: 1.5;
    box-shadow: inset 0 1px 2px rgba(15, 23, 42, .04);
    transition: border-color .18s, box-shadow .18s, background .18s;
}

/* Tall, like the sales page's and unlike the demo page's: the scope of the
   quote is a required field, so it is somewhere the visitor is meant to write
   rather than an optional afterthought. */
.qgq-form textarea { min-height: 138px; resize: vertical; }

.qgq-form input::placeholder,
.qgq-form textarea::placeholder { color: #a3a0bb; }

.qgq-form input:not([type="checkbox"]):hover,
.qgq-form select:hover,
.qgq-form textarea:hover { border-color: #d6d0f0; }

/* Beats the flow's focus:ring-2 utility on specificity, so the ring is this
   page's violet rather than the stock indigo. */
.qgq-form input:not([type="checkbox"]):focus,
.qgq-form select:focus,
.qgq-form textarea:focus {
    outline: none;
    background: #fff;
    border-color: #7c3aed;
    box-shadow: 0 0 0 4px rgba(124, 58, 237, .14), 0 1px 2px rgba(15, 23, 42, .05);
}

/* Blazor stamps .invalid on a field that failed validation — the border says so
   before the message underneath is read. */
.qgq-form input.invalid:not([type="checkbox"]),
.qgq-form select.invalid,
.qgq-form textarea.invalid {
    border-color: #fda4af;
    background: #fff7f8;
}

.qgq-form input.invalid:focus,
.qgq-form select.invalid:focus,
.qgq-form textarea.invalid:focus {
    border-color: #f43f5e;
    box-shadow: 0 0 0 4px rgba(244, 63, 94, .14);
}

/* Field labels. Qualified on .block, which is what separates a field label from
   the consent row's — that one is a flex label owned by <ConsentCheck /> and
   must keep its own layout. */
.qgq-form label.block > span:first-child {
    display: block;
    margin-bottom: 7px;
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: .005em;
    color: #334155;
}

/* The helper line under a field, and the flow's closing reassurance note. */
.qgq-form label.block > span:last-child:not(:first-child),
.qgq-form form > p {
    display: block;
    margin-top: 7px;
    font-size: 12px;
    line-height: 1.6;
    color: #7c7a93;
}

.qgq-form .validation-message {
    display: block;
    margin-top: 7px;
    font-size: 12px;
    font-weight: 600;
    color: #e11d48;
}

/* Dial code + number. Keyed on .flex — the wrapper is the only span in a field
   that is a flex row, and matching it by position would put display:flex on
   every other field's <input> as collateral. */
.qgq-form label.block > span.flex {
    display: flex;
    align-items: stretch;
    gap: 9px;
}

.qgq-form label.block > span.flex > span:first-child {
    display: flex;
    align-items: center;
    gap: 2px;
    flex: 0 0 auto;
    width: 96px;
    padding: 0 6px 0 13px;
    border-radius: 13px;
    border: 1px solid #e6e3f5;
    background: #f4f1fd;
    color: #6b7280;
    font-size: 14.5px;
}

/* Puts the general field rule back: this input is chrome inside the box above,
   not a box of its own. */
.qgq-form label.block > span.flex > span:first-child input {
    width: 100%;
    padding: 11px 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    font-weight: 700;
    color: #0b1020;
}

.qgq-form label.block > span.flex > span:first-child input:focus {
    background: transparent;
    box-shadow: none;
}

/* Verification code. maxlength="6" is what distinguishes it from the dial code,
   the page's only other numeric input. */
.qgq-form input[maxlength="6"] {
    padding: 15px 12px;
    font-size: 26px;
    font-weight: 800;
    text-align: center;
    letter-spacing: .42em;
    text-indent: .42em;
    color: #1e1b4b;
    background: #fff;
}

/* The explainer panel — what submitting actually does. Its bg-indigo-50/70 has
   no rule in the bundle, so this is the only fill it has ever had. */
.qgq-form form > div[class*="bg-indigo-50"] {
    position: relative;
    padding: 16px 18px 16px 20px;
    border-radius: 15px;
    border: 1px solid #e4e0fb;
    border-left: 0;
    background: linear-gradient(135deg, #f8f6ff, #f4f1fe);
    font-size: 13px;
    line-height: 1.7;
    color: #4a4763;
}

.qgq-form form > div[class*="bg-indigo-50"]::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    border-radius: 15px 0 0 15px;
    background: linear-gradient(180deg, #7c3aed, #4f46e5);
}

/* Consent. Boxed so the one thing being agreed to is not a loose line of small
   print between the explainer and the submit button. */
.qgq-form form > div.pt-1 {
    padding: 14px 16px;
    border-radius: 15px;
    border: 1px solid #eceaf7;
    background: #fcfcfe;
}

.qgq-form input[type="checkbox"] {
    width: 17px;
    height: 17px;
    accent-color: #7c3aed;
    cursor: pointer;
}

/* Status panels — alert, status and the success screens. Keyed on the ARIA
   roles the flow already sets, so nothing here depends on its colour classes. */
.qgq-form div[role="alert"],
.qgq-form div[role="status"] {
    border-radius: 15px;
    font-size: 13.5px;
    line-height: 1.6;
}

/* Step headings on verify / set-password / done. */
.qgq-form h2 { letter-spacing: -.02em; }

/* Buttons. The flow's .startFreeTrial gradient and .bookADemo fill are left
   alone — only geometry, shadow and the pressed states change, so a column of
   full-width fields does not end in a shrink-to-fit control. Anchored on button
   so the Done step's <a> — which sits inside a narrow success panel — is left
   as it is. */
.qgq-form button.startFreeTrial,
.qgq-form button.bookADemo {
    width: 100%;
    padding: 14px 24px;
    border-radius: 14px;
    font-size: 15px;
    font-weight: 700;
    letter-spacing: -.01em;
}

.qgq-form button.startFreeTrial {
    box-shadow: 0 16px 34px -14px rgba(79, 70, 229, .75), 0 2px 6px -2px rgba(79, 70, 229, .3);
}

.qgq-form button.startFreeTrial:hover:not(:disabled) {
    transform: translateY(-1px);
    box-shadow: 0 22px 42px -14px rgba(79, 70, 229, .85), 0 3px 8px -2px rgba(79, 70, 229, .35);
}

.qgq-form button.startFreeTrial:active:not(:disabled) { transform: translateY(0); }

.qgq-form button.startFreeTrial:disabled,
.qgq-form button.bookADemo:disabled {
    opacity: .55;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
}

.qgq-form button.bookADemo:hover:not(:disabled) { border-color: #cfc6f0; }

/* The two text-only escape hatches under the code field. */
.qgq-form button.underline {
    font-size: 12.5px;
    color: #6d6a86;
    text-underline-offset: 3px;
}

.qgq-form button.underline:hover { color: #4f46e5; }

/* ── progress rail ──────────────────────────────────────────────────── */
/* The flow's step list is its only direct-child <ol>; the success screen's
   next-steps list is a <ul> inside a panel, so it is not touched. Boxed and
   pulled to the card's edges so the rail reads as a header for the form rather
   than as its first row of content. */
.qgq-form > ol {
    gap: 10px 14px;
    margin: -6px -6px 26px;
    padding: 13px 16px;
    border-radius: 15px;
    background: linear-gradient(135deg, #faf9ff, #f5f2fe);
    border: 1px solid #efecfb;
}

.qgq-form > ol li > span:first-child {
    width: 25px;
    height: 25px;
    border-radius: 9px;
    font-size: 11.5px;
    font-weight: 800;
}

/* The one place a utility class is selected on here. The flow marks the live
   step with bg-indigo-600 and nothing else distinguishes it structurally, so
   the halo has to key on that. */
.qgq-form > ol li > span.bg-indigo-600 {
    box-shadow: 0 0 0 4px rgba(79, 70, 229, .14);
}

.qgq-form > ol li > span:nth-child(2) { font-size: 12.5px; }

/* The em dash between steps, redrawn as a rule. font-size:0 hides the glyph;
   the box then carries the line. */
.qgq-form > ol li > span:nth-child(3) {
    width: 20px;
    height: 2px;
    margin-left: 4px;
    border-radius: 99px;
    font-size: 0;
    background: #e2ddf6;
}

/* ── aside ──────────────────────────────────────────────────────────── */
.qgq-aside {
    position: sticky;
    top: 96px;
    display: grid;
    gap: 20px;
    min-width: 0;
}

.qgq-card {
    position: relative;
    overflow: hidden;
    padding: 26px 26px 28px;
    border-radius: 24px;
    background: #fff;
    border: 1px solid #ebeaf5;
    box-shadow: 0 30px 66px -44px rgba(79, 70, 229, .55);
}

.qgq-card::after {
    content: "";
    position: absolute;
    width: 280px;
    height: 280px;
    top: -200px;
    right: -110px;
    border-radius: 50%;
    pointer-events: none;
    background: radial-gradient(circle, rgba(162, 45, 234, .12), transparent 66%);
}

.qgq-card__head {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 22px;
}

.qgq-card__ic {
    width: 38px;
    height: 38px;
    flex: 0 0 auto;
    border-radius: 12px;
    display: grid;
    place-items: center;
    color: #fff;
    background: linear-gradient(135deg, #4f46e5, #7c3aed);
    box-shadow: 0 14px 28px -14px rgba(79, 70, 229, .95);
}

/* Amber means "a number that is already published" everywhere on this page —
   the routes card and nothing else. */
.qgq-card__ic--amber {
    background: linear-gradient(135deg, #d97706, #f59e0b);
    box-shadow: 0 14px 28px -14px rgba(217, 119, 6, .95);
}

.qgq-card__ic svg { width: 19px; height: 19px; }

.qgq-card__title {
    font-size: 17px;
    line-height: 1.3;
    font-weight: 800;
    letter-spacing: -.02em;
    color: #0b1020;
    margin: 0;
}

/* ── step rail ──────────────────────────────────────────────────────── */
/* A numbered rail rather than the sales page's checklist: quoting is a sequence
   with an end the visitor is waiting for, so the connector between nodes is
   carrying real meaning. */
.qgq-steps {
    position: relative;
    margin: 0;
    padding: 0;
    list-style: none;
}

.qgq-step {
    position: relative;
    display: flex;
    gap: 14px;
}

.qgq-step + .qgq-step { margin-top: 20px; }

/* Connector between the numbered nodes. 16px + the 2px rule centres it under a
   34px badge; the negative bottom carries it across the 20px gap to the next. */
.qgq-step:not(:last-child)::before {
    content: "";
    position: absolute;
    left: 16px;
    top: 40px;
    bottom: -20px;
    width: 2px;
    border-radius: 99px;
    background: linear-gradient(180deg, #c7d2fe, #ede9fe);
}

.qgq-step__n {
    position: relative;
    width: 34px;
    height: 34px;
    flex: 0 0 auto;
    border-radius: 99px;
    display: grid;
    place-items: center;
    font-size: 13px;
    font-weight: 800;
    color: #fff;
    background: linear-gradient(135deg, #4f46e5, #7c3aed);
    box-shadow: 0 12px 24px -14px rgba(79, 70, 229, .95), 0 0 0 4px #f1efff;
}

.qgq-step__body { min-width: 0; }

.qgq-step__t {
    font-size: 14px;
    font-weight: 700;
    letter-spacing: -.01em;
    line-height: 1.4;
    color: #0b1020;
    margin: 6px 0 5px;
}

.qgq-step__d {
    font-size: 12.5px;
    line-height: 1.65;
    color: #64748b;
    margin: 0;
}

/* ── published-price routes ─────────────────────────────────────────── */
/* Each route is a target in its own right, so the whole row lights up rather
   than only the link text — the description is part of what is being chosen. */
.qgq-routes {
    position: relative;
    display: grid;
    gap: 10px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.qgq-route {
    position: relative;
    padding: 13px 15px;
    border-radius: 15px;
    border: 1px solid #f2ecdf;
    background: #fdfcfa;
    transition: border-color .18s, background .18s, transform .18s, box-shadow .18s;
}

.qgq-route:hover {
    transform: translateY(-1px);
    border-color: #fcd9a0;
    background: #fffbf3;
    box-shadow: 0 12px 26px -18px rgba(217, 119, 6, .85);
}

.qgq-route__link {
    display: block;
    font-size: 13.5px;
    font-weight: 700;
    letter-spacing: -.01em;
    color: #b45309;
    text-decoration: none;
    transition: color .18s;
}

/* Stretches the anchor over the whole row, so the padded card is the hit area
   without nesting anything else inside a link. */
.qgq-route__link::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 15px;
}

.qgq-route:hover .qgq-route__link { color: #92400e; }

.qgq-route__d {
    display: block;
    margin-top: 3px;
    font-size: 12px;
    line-height: 1.6;
    color: #7c7a93;
}

/* The closing line under the routes — when asking for a quote is worth it.
   Ruled off rather than boxed: it is a caveat on the list above, not a fourth
   item in it. */
.qgq-note {
    position: relative;
    margin: 20px 0 0;
    padding-top: 16px;
    border-top: 1px solid #f1eff8;
    font-size: 12px;
    line-height: 1.7;
    color: #7c7a93;
}

/* ── responsive ─────────────────────────────────────────────────────── */
@media (max-width: 1180px) {
    .qgq-layout { grid-template-columns: minmax(0, 1fr) 330px; gap: 26px; }
}

@media (max-width: 1024px) {
    /* The aside drops below the form, so it stops being sticky — a panel that
       tracks the viewport once it is full-width covers the content behind it.
       Its two cards go side by side rather than stacking into a long tail. */
    .qgq-layout { grid-template-columns: minmax(0, 1fr); gap: 28px; }

    .qgq-aside {
        position: static;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        align-items: start;
    }
}

@media (max-width: 760px) {
    .qgq-hero { padding: 44px 0 132px; }
    .qgq-hero__title { max-width: none; }
    .qgq-chips { gap: 8px; }
    .qgq-chip { font-size: 12.5px; padding: 8px 15px; }

    .qgq-main { margin-top: -88px; padding-bottom: 60px; }
    .qgq-formcard__in { padding: 24px 20px 22px; }

    /* The rail wraps to two rows on a phone, so the negative side margins that
       bleed it to the card edge on desktop would crowd it. */
    .qgq-form > ol { margin: 0 0 22px; padding: 12px 13px; gap: 9px 11px; }
    .qgq-form > ol li > span:nth-child(3) { width: 12px; margin-left: 2px; }

    .qgq-form label.block > span.flex > span:first-child { width: 88px; }
    .qgq-form input[maxlength="6"] { font-size: 22px; letter-spacing: .3em; text-indent: .3em; }

    .qgq-aside { grid-template-columns: minmax(0, 1fr); }
    .qgq-card { padding: 22px 20px 24px; }
}

@media (prefers-reduced-motion: reduce) {
    .qgq-glow i { animation: none !important; }
    .qgq-route:hover { transform: none; }
}
