@charset "UTF-8";

/* ===================================================================
 *
 *  aBolsillo — stylesheet
 *
 *  No framework and no vendor CSS. The icons are inline SVG in the markup,
 *  so the page carries no icon font at all.
 *
 *  TOC:
 *  # tokens
 *  # reset and base
 *  # typography
 *  # layout primitives
 *  # buttons
 *  # reveal on scroll
 *  # header
 *  # hero
 *  # about
 *  # how it works (stats + steps)
 *  # features
 *  # pricing
 *  # download
 *  # footer
 *  # back to top
 *  # language switch
 *  # faq page
 *  # legal page
 *
 *  Every colour, size and spacing step is a custom property in # tokens,
 *  so changing the palette means editing :root and nothing else.
 *
 * ------------------------------------------------------------------- */


/* ===================================================================
 * # tokens
 * ------------------------------------------------------------------- */

:root {
    /* brand -- from the app's docs/BRANDING.md */
    --c-primary:        #6F4E37;
    --c-primary-hover:  #634531;
    --c-primary-deep:   #523928;
    /* the primary fails contrast on dark grounds; this is its stand-in */
    --c-accent:         #C19A6B;

    /* neutrals */
    --c-ink:            #16110d;
    --c-body:           #4a4038;
    --c-muted:          #7b7169;
    --c-line:           #e7e1db;
    --c-surface:        #ffffff;
    --c-surface-warm:   #faf7f4;
    --c-dark:           #1a1512;
    --c-dark-soft:      #241d18;
    --c-on-dark:        #f4efea;
    --c-on-dark-muted:  rgba(244, 239, 234, .62);

    /* type */
    /* Montserrat is the app's typeface (`appFontFamily` in its app_theme.dart),
       so the headings and the chrome speak with the same voice the product
       does. Body copy stays on Nunito Sans: this site carries 68 FAQ answers
       and a full legal document, and Montserrat is wide going at that length. */
    --f-sans:  "Nunito Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --f-head:  "Montserrat", var(--f-sans);

    /* A fluid scale: no step needs its own media query. The upper bound of
       each step is the size this site has always used at desktop width --
       72px for the hero, 55px for a section heading, 28px for a card title,
       18px for body copy -- so the page reads at the weight it should, and
       only tightens on narrow screens. */
    --t-xs:    0.875rem;                                        /* 14 */
    --t-sm:    1rem;                                            /* 16 */
    --t-base:  clamp(1.0625rem, 1rem    + 0.30vw, 1.125rem);    /* 17 -> 18 */
    --t-lg:    clamp(1.25rem,   1.10rem + 0.60vw, 1.5rem);      /* 20 -> 24 */
    --t-xl:    clamp(1.375rem,  1.15rem + 0.90vw, 1.75rem);     /* 22 -> 28 */
    --t-2xl:   clamp(1.75rem,   1.40rem + 1.40vw, 2.5rem);      /* 28 -> 40 */
    --t-3xl:   clamp(2.125rem,  1.50rem + 2.60vw, 3.4rem);      /* 34 -> 55 */
    --t-4xl:   clamp(2.25rem,   1.50rem + 3.60vw, 4rem);        /* 36 -> 64 */

    /* spacing, on a 4px rhythm */
    --s-1:  0.25rem;
    --s-2:  0.5rem;
    --s-3:  0.75rem;
    --s-4:  1rem;
    --s-5:  1.5rem;
    --s-6:  2rem;
    --s-7:  2.5rem;
    --s-8:  3rem;
    --s-9:  4rem;
    --s-10: 5rem;
    --s-11: 6rem;
    --s-12: 8rem;

    /* Section rhythm, tightening on small screens on its own. Read it as the
       air a section keeps on its own; where two sections meet, the lower one
       takes 55% of it, because otherwise the two pads stack and leave a gap
       the height of half a screen. */
    --s-section: clamp(4.5rem, 2rem + 7.5vw, 9.5rem);

    --radius:      14px;
    --radius-sm:   10px;
    --radius-pill: 999px;

    --shadow-sm: 0 1px 2px rgba(22, 17, 13, .05);
    --shadow-md: 0 6px 24px -8px rgba(22, 17, 13, .14);
    --shadow-lg: 0 18px 48px -18px rgba(22, 17, 13, .28);

    --wrap:      1240px;    /* ~1192px of content once the gutters come off */
    --wrap-hero: 1340px;    /* the cover runs wider than the sections below it */
    --wrap-text: 780px;

    --header-h: 92px;

    --ease: cubic-bezier(.2, .7, .3, 1);

    /* The hero photograph carries the white headline, so it needs a tint dark
       enough to hold the contrast and light enough to still read as a photo.
       Declared once and used by both branches of the @supports below. */
    --stats-tint:
        linear-gradient(rgba(20, 16, 13, .72), rgba(20, 16, 13, .82));

    --hero-tint:
        radial-gradient(120% 90% at 78% 12%, rgba(111, 78, 55, .42) 0%, transparent 58%),
        radial-gradient(90% 80% at 8% 92%, rgba(193, 154, 107, .12) 0%, transparent 60%),
        linear-gradient(168deg, rgba(36, 29, 24, .84) 0%, rgba(26, 21, 18, .76) 62%, rgba(20, 16, 13, .90) 100%);
}


/* ===================================================================
 * # reset and base
 * ------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    /* Every in-page anchor clears the fixed header without JS, on every page
       -- including the ones where the anchor's target does not exist. */
    scroll-padding-top: calc(var(--header-h) + var(--s-4));
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }
}

body {
    margin: 0;
    background-color: var(--c-surface);
    color: var(--c-body);
    font-family: var(--f-sans);
    font-size: var(--t-base);
    line-height: 1.75;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

img, picture, svg, video { display: block; max-width: 100%; }
img { height: auto; }

a { color: var(--c-primary); text-decoration: none; transition: color .18s var(--ease); }
a:hover { color: var(--c-primary-hover); }

ul, ol { margin: 0; padding: 0; }
li { list-style: none; }

button { font: inherit; color: inherit; }

:focus-visible {
    outline: 3px solid var(--c-accent);
    outline-offset: 3px;
    border-radius: 4px;
}

.u-visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}


/* ===================================================================
 * # typography
 * ------------------------------------------------------------------- */

h1, h2, h3, h4 {
    margin: 0 0 var(--s-4);
    font-family: var(--f-head);
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.02em;
    color: var(--c-ink);
}

/* Card and column titles are small enough that 600 reads light against the
   body text around them. */
h3, h4 { font-weight: 700; }

h1 { font-size: var(--t-4xl); }
h2 { font-size: var(--t-3xl); }
h3 { font-size: var(--t-xl); }
h4 { font-size: var(--t-lg); }

p { margin: 0 0 var(--s-4); }
p:last-child { margin-bottom: 0; }

strong { font-weight: 700; color: var(--c-ink); }

/* the section intro: a heading with a lead paragraph under it */
.section-head {
    max-width: var(--wrap-text);
    margin: 0 auto var(--s-10);
    text-align: center;
}

.section-head--spaced { margin-top: var(--s-11); }

.section-head .lead {
    font-size: var(--t-lg);
    color: var(--c-muted);
    margin-bottom: 0;
}

/* the little brown rule that opens a section */
.section-head::before {
    content: "";
    display: block;
    width: 44px;
    height: 3px;
    margin: 0 auto var(--s-6);
    background-color: var(--c-primary);
    border-radius: var(--radius-pill);
}

.s-hero + * .section-head::before { background-color: var(--c-primary); }


/* ===================================================================
 * # layout primitives
 * ------------------------------------------------------------------- */

.wrap {
    width: 100%;
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: var(--s-5);
}

.section { padding-block: var(--s-section); }

/* A section that follows another -- or the cover, which ends in plenty of air
   of its own -- does not need a full pad again on top of the one above it. */
.s-hero + .section,
.section + .section { padding-top: calc(var(--s-section) * .55); }

.section--warm { background-color: var(--c-surface-warm); }

.section--dark {
    background-color: var(--c-dark);
    color: var(--c-on-dark-muted);
}

.section--dark h2,
.section--dark h3 { color: var(--c-on-dark); }

.grid { display: grid; gap: var(--s-5); }

@media (min-width: 700px) {
    .grid--2 { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 940px) {
    .grid--3 { grid-template-columns: repeat(3, 1fr); }
    .grid--4 { grid-template-columns: repeat(4, 1fr); }
}

@media (min-width: 700px) and (max-width: 939px) {
    .grid--3,
    .grid--4 { grid-template-columns: repeat(2, 1fr); }
}


/* ===================================================================
 * # buttons
 * ------------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s-2);
    padding: var(--s-3) var(--s-6);
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    background-color: transparent;
    font-family: var(--f-head);
    font-size: var(--t-sm);
    font-weight: 700;
    letter-spacing: .01em;
    line-height: 1.2;
    text-align: center;
    cursor: pointer;
    transition: background-color .18s var(--ease),
                border-color .18s var(--ease),
                color .18s var(--ease),
                transform .18s var(--ease);
}

.btn:active { transform: translateY(1px); }

.btn--primary {
    background-color: var(--c-primary);
    color: #fff;
}

.btn--primary:hover {
    background-color: var(--c-primary-hover);
    color: #fff;
}

.btn--ghost {
    border-color: rgba(244, 239, 234, .28);
    color: var(--c-on-dark);
}

.btn--ghost:hover {
    border-color: var(--c-accent);
    color: var(--c-accent);
}

.btn--lg { padding: var(--s-4) var(--s-7); font-size: var(--t-base); }

.btn--block { display: flex; width: 100%; }

.btn--disabled {
    background-color: var(--c-line);
    color: var(--c-muted);
    cursor: not-allowed;
}

.btn--disabled:active { transform: none; }


/* ===================================================================
 * # reveal on scroll
 *
 * The class is added by js/app.js through an IntersectionObserver. With JS
 * off, or with reduced motion asked for, everything is simply visible.
 * ------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
    .js .reveal {
        opacity: 0;
        transform: translateY(14px);
        transition: opacity .5s var(--ease), transform .5s var(--ease);
    }

    .js .reveal.is-in {
        opacity: 1;
        transform: none;
    }
}


/* ===================================================================
 * # header
 * ------------------------------------------------------------------- */

.site-header {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 50;
    height: var(--header-h);
    display: flex;
    align-items: center;
    transition: background-color .25s var(--ease), box-shadow .25s var(--ease);
}

/* Transparent over the dark hero, solid once it leaves it. The logo is
   light artwork, so the header can never sit transparent over a white
   page -- which is why the inner pages force the solid state. */
.site-header.is-stuck,
.page-inner .site-header {
    background-color: var(--c-dark);
    box-shadow: var(--shadow-md);
}

.site-header .wrap {
    display: flex;
    align-items: center;
    gap: var(--s-5);
}

.site-logo { flex: none; line-height: 0; }
/* 165x37 keeps the 1024x229 artwork's ratio. It sat at 130px, which left the
   wordmark visibly slighter than the button beside it. */
.site-logo img { width: 165px; height: 37px; }

/* Above the drop-down breakpoint the list and the CTA sit on one line; the
   media query below turns this back into a stacked block. */
.site-nav {
    display: flex;
    align-items: center;
    gap: var(--s-6);
    margin-left: auto;
}

.site-nav__list {
    display: flex;
    align-items: center;
    gap: var(--s-5);
}

.site-nav__list a {
    font-family: var(--f-head);
    font-size: var(--t-sm);
    font-weight: 400;
    color: var(--c-on-dark-muted);
    white-space: nowrap;
}

.site-nav__list a:hover,
.site-nav__list .is-current a {
    color: var(--c-on-dark);
}

.site-nav__login a { color: var(--c-accent); }
.site-nav__login a:hover { color: #fff; }

.site-nav__cta .btn { padding-inline: var(--s-5); }

.nav-toggle {
    display: none;
    margin-left: auto;
    padding: var(--s-2);
    border: 0;
    background: none;
    cursor: pointer;
}

.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
    display: block;
    width: 24px;
    height: 2px;
    border-radius: 2px;
    background-color: var(--c-on-dark);
    transition: transform .22s var(--ease), opacity .22s var(--ease);
}

.nav-toggle__bars { position: relative; }

.nav-toggle__bars::before,
.nav-toggle__bars::after {
    content: "";
    position: absolute;
    left: 0;
}

.nav-toggle__bars::before { top: -7px; }
.nav-toggle__bars::after  { top: 7px; }

.nav-toggle[aria-expanded="true"] .nav-toggle__bars { background-color: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after  { transform: translateY(-7px) rotate(-45deg); }

/* The drop-down starts at 900px. Below that the logo, the five nav items and
   the CTA stop fitting on one line, and the CTA is the piece a visitor needs
   most -- so the whole nav moves into the drop-down rather than the button
   being dropped from the row. */
@media (max-width: 900px) {
    .nav-toggle { display: block; }

    /* `display: none` cannot be transitioned, which is why the panel used to
       appear and vanish in one frame. It stays in the layer instead and is
       hidden by opacity, a small offset and visibility -- all three animatable.
       It is absolutely positioned, so nothing below it moves either way, and
       `visibility` keeps it out of the tab order while closed. */
    .site-nav {
        position: absolute;
        top: var(--header-h);
        left: 0;
        right: 0;
        display: block;
        gap: 0;
        padding: var(--s-5);
        background-color: var(--c-dark);
        box-shadow: var(--shadow-lg);

        opacity: 0;
        visibility: hidden;
        transform: translateY(-10px);
        transition: opacity .22s var(--ease),
                    transform .22s var(--ease),
                    visibility .22s;
    }

    .site-nav.is-open {
        opacity: 1;
        visibility: visible;
        transform: none;
    }

    .site-nav__list {
        flex-direction: column;
        align-items: stretch;
        gap: 0;
    }

    .site-nav__list a {
        display: block;
        padding: var(--s-3) var(--s-2);
        font-size: var(--t-base);
        border-bottom: 1px solid rgba(244, 239, 234, .09);
    }

    .site-nav__cta {
        margin-top: var(--s-4);
    }

    .site-nav__cta .btn { display: flex; width: 100%; }
}


/* ===================================================================
 * # hero
 * ------------------------------------------------------------------- */

.s-hero {
    position: relative;
    display: flex;
    align-items: center;
    min-height: 100svh;
    padding-block: calc(var(--header-h) + var(--s-9)) var(--s-9);
    background-color: var(--c-dark);
    background-image: var(--hero-tint), url(../images/architecture-facade.jpg);
    background-size: cover;
    background-position: center;
    color: var(--c-on-dark-muted);
    overflow: hidden;
}

/* WebP where it is understood, which is every current browser; the JPG above
   stays as the fallback for anything that is not. */
@supports (background-image: image-set(url("x.webp") type("image/webp"))) {
    .s-hero {
        background-image: var(--hero-tint),
            image-set(url(../images/architecture-facade.webp) type("image/webp"),
                      url(../images/architecture-facade.jpg)  type("image/jpeg"));
    }
}

.s-hero__inner {
    display: grid;
    gap: var(--s-8);
    align-items: center;
    max-width: var(--wrap-hero);
}

/* Two columns only once the headline has room to keep its two lines. Below
   this the cover stacks, which reads better than a slogan broken into four
   pieces beside a phone. The text track carries the minimum and the artwork
   yields to it, so the headline never gets squeezed by the image. */
@media (min-width: 1120px) {
    .s-hero__inner {
        grid-template-columns: minmax(660px, 1fr) minmax(300px, 580px);
        gap: var(--s-10);
    }
}

/* The app is not out of beta yet, and the page says so before the slogan
   rather than after it. The accent carries the primary's job here: the brown
   fails contrast on the photograph. */
.s-hero__beta {
    display: inline-block;
    margin-bottom: var(--s-4);
    padding: var(--s-1) var(--s-3);
    border: 1px solid rgba(193, 154, 107, .45);
    border-radius: var(--radius-pill);
    font-family: var(--f-head);
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--c-accent);
    background-color: rgba(193, 154, 107, .10);
}

.s-hero h1 {
    color: var(--c-on-dark);
    margin-bottom: var(--s-5);
    text-wrap: balance;
}

.s-hero__lead {
    max-width: 52ch;
    font-size: var(--t-lg);
    color: var(--c-on-dark-muted);
    margin-bottom: var(--s-7);
}

/* Capped, because when the cover stacks the artwork would otherwise run the
   full width of the container. */
.s-hero__art img {
    margin-inline: auto;
    max-width: min(100%, 580px);
}

.s-hero__social {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-5);
    margin-top: var(--s-8);
}

.s-hero__social a {
    font-family: var(--f-head);
    font-size: var(--t-xs);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--c-on-dark-muted);
}

.s-hero__social a:hover { color: var(--c-accent); }

.s-hero__scroll {
    position: absolute;
    left: 50%;
    bottom: var(--s-5);
    transform: translateX(-50%);
    display: none;
    align-items: center;
    gap: var(--s-2);
    font-family: var(--f-head);
    font-size: var(--t-xs);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--c-on-dark-muted);
}

.s-hero__scroll:hover { color: var(--c-accent); }

/* A slow drift on the arrow, to say "there is more below" without asking
   for attention. Deliberately the SVG and not the whole control: the parent
   carries translateX(-50%) for its own centring, and animating its transform
   would overwrite that and slide the label off centre. Moving the arrow
   alone also reads calmer -- the word stays put and only the pointer breathes.

   4px over 2.4s is the whole effect. Anything faster or taller stops being a
   hint and becomes a thing that flashes in the corner of the eye for as long
   as the visitor is reading the headline.

   No reduced-motion rule is needed here: the global block in # reset already
   collapses every animation to .01ms and one iteration, and this keyframe
   both starts and ends at translateY(0), so that collapse lands on neutral
   rather than leaving the arrow stuck 4px down. */
@keyframes hero-scroll-hint {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(4px); }
}

.s-hero__scroll svg {
    animation: hero-scroll-hint 2.4s ease-in-out infinite;
}

@media (min-width: 1120px) and (min-height: 720px) {
    .s-hero__scroll { display: flex; }
}


/* ===================================================================
 * # about
 * ------------------------------------------------------------------- */

/* Four cards in a grid, no carousel: at desktop the four sit side by side
   and there is nothing to page through. Below 700px the grid becomes a
   swipeable row using scroll-snap, which is the one width where paging
   genuinely helps. */
.about-cards { counter-reset: about; }

@media (min-width: 700px) {
    .about-cards { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1280px) {
    .about-cards { grid-template-columns: repeat(4, 1fr); }
}

/* The icon sits beside the title rather than stacked above it, so the card
   opens with one line you read in a single go.

   A column flexbox, NOT a grid with `align-items: center`. That centred every
   child, which meant the paragraph floated in the middle of whatever height
   the tallest card in the row imposed, with uneven air above and below it.
   Here the head and the paragraph stack from the top and any extra height
   from a taller sibling falls below the text, where it belongs. */
.about-card {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding: var(--s-7);
    background-color: var(--c-surface);
    border: 1px solid var(--c-line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
}

/* One row, and the only thing centred is the icon against the title. */
.about-card__head {
    display: flex;
    align-items: center;
    gap: var(--s-4);
    margin-bottom: var(--s-5);
}

.about-card__icon { flex: none; }

.about-card h3 {
    font-size: var(--t-lg);
    color: var(--c-primary);
    margin-bottom: 0;
}

.about-card p { margin: 0; }

.about-card p { margin-bottom: 0; font-size: var(--t-base); }

@media (max-width: 699px) {
    .about-cards {
        grid-auto-flow: column;
        grid-auto-columns: 82%;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        padding-bottom: var(--s-3);
        margin-inline: calc(var(--s-5) * -1);
        padding-inline: var(--s-5);
        scrollbar-width: thin;
    }

    .about-card { scroll-snap-align: start; }
}


/* ===================================================================
 * # how it works (stats + steps)
 * ------------------------------------------------------------------- */

.s-how { background-color: var(--c-surface-warm); }

.stats-band {
    position: relative;
    display: grid;
    gap: var(--s-6);
    padding: var(--s-11) var(--s-7);
    border-radius: var(--radius);
    background-color: var(--c-dark);
    background-image: var(--stats-tint), url(../images/checkout-payment.jpg);
    background-size: cover;
    background-position: center;
    text-align: center;
    overflow: hidden;
}

@supports (background-image: image-set(url("x.webp") type("image/webp"))) {
    .stats-band {
        background-image: var(--stats-tint),
            image-set(url(../images/checkout-payment.webp) type("image/webp"),
                      url(../images/checkout-payment.jpg)  type("image/jpeg"));
    }
}

@media (min-width: 700px) {
    .stats-band { grid-template-columns: repeat(2, 1fr); }
}

.stat__num {
    display: block;
    font-family: var(--f-head);
    font-size: var(--t-4xl);
    font-weight: 900;
    line-height: 1;
    color: var(--c-accent);
}

.stat__label {
    display: block;
    margin-top: var(--s-2);
    font-size: var(--t-sm);
    color: var(--c-on-dark-muted);
}

/* Two columns, not four: each step is a sentence, not a label, and it needs
   the width. The number is a solid disc carrying the brand colour, sitting to
   the left of the text rather than inline with the heading -- it is the piece
   that makes the sequence read as a sequence. */
.steps {
    counter-reset: step;
    display: grid;
    gap: var(--s-9) var(--s-8);
    max-width: 1080px;
    margin: var(--s-10) auto 0;
}

@media (min-width: 780px) {
    .steps { grid-template-columns: repeat(2, 1fr); }
}

.step {
    counter-increment: step;
    position: relative;
    padding-left: 84px;
    list-style: none;
}

.step::before {
    content: counter(step);
    position: absolute;
    left: 0;
    top: -2px;
    display: grid;
    place-items: center;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background-color: var(--c-primary);
    color: #fff;
    font-family: var(--f-head);
    font-size: var(--t-lg);
    font-weight: 700;
    line-height: 1;
}

.step h3 {
    font-size: var(--t-lg);
    margin-bottom: var(--s-3);
}

.step p { font-size: var(--t-base); margin-bottom: 0; }

@media (max-width: 520px) {
    .step { padding-left: 68px; }
    .step::before { width: 46px; height: 46px; font-size: var(--t-base); }
}


/* ===================================================================
 * # features
 * ------------------------------------------------------------------- */

.feature {
    padding: var(--s-7);
    border: 1px solid var(--c-line);
    border-radius: var(--radius);
    background-color: var(--c-surface);
    transition: border-color .2s var(--ease),
                box-shadow .2s var(--ease),
                transform .2s var(--ease);
}

.feature:hover {
    border-color: rgba(111, 78, 55, .35);
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

/* A final card left alone on its row reads as an accident rather than a
   choice. When the count does not divide by three, the last one spans the
   row instead -- which keeps the grid honest at 10 cards, and at 13, and
   at any other count that leaves a remainder of one. */
@media (min-width: 940px) {
    .grid--3 > .feature:last-child:nth-child(3n + 1) {
        grid-column: 1 / -1;
    }

    .grid--3 > .feature:last-child:nth-child(3n + 1) p {
        max-width: 62ch;
    }
}

/* One icon treatment for both card families, so the two sections read as the
   same system rather than as two designs. */
.feature__icon,
.about-card__icon {
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    border-radius: var(--radius-sm);
    background-color: rgba(111, 78, 55, .09);
    color: var(--c-primary);
}

/* Only the stacked variant needs to push the title down. Putting this on the
   shared rule gave the about card's icon a phantom 16px below it, which made
   its row taller than the icon and left the title sitting off-centre. */
.feature__icon { margin-bottom: var(--s-4); }

.feature__icon svg,
.about-card__icon svg { width: 24px; height: 24px; }

.feature h3 { font-size: var(--t-lg); margin-bottom: var(--s-2); }

.feature p { font-size: var(--t-base); margin-bottom: 0; }


/* ===================================================================
 * # pricing
 * ------------------------------------------------------------------- */

/* The two cards stretch to the same height on purpose: `.plan .btn` has
   `margin-top: auto`, so both calls to action land on the same line no matter
   how much copy each plan carries. */
.plans {
    max-width: 880px;
    margin-inline: auto;
}

.plan {
    display: flex;
    flex-direction: column;
    padding: var(--s-7) var(--s-6);
    border: 1px solid var(--c-line);
    border-radius: var(--radius);
    background-color: var(--c-surface);
}

/* The free plan is the one being offered, so it carries the brand colour and
   inverts: white text on brown, and a white button against it. */
.plan--featured {
    background-color: var(--c-primary);
    border-color: var(--c-primary);
    box-shadow: var(--shadow-md);
    color: rgba(255, 255, 255, .88);
}

.plan--featured .plan__name { color: rgba(255, 255, 255, .72); }
.plan--featured .plan__price { color: #ffffff; }
.plan--featured .plan__per { color: rgba(255, 255, 255, .72); }
.plan--featured .plan__features svg { color: #ffffff; }

.plan--featured .btn--primary {
    background-color: #ffffff;
    color: var(--c-primary-deep);
}

.plan--featured .btn--primary:hover {
    background-color: var(--c-primary-deep);
    color: #ffffff;
}

.plan__name {
    font-size: var(--t-sm);
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--c-primary);
    margin-bottom: var(--s-3);
}

.plan__price {
    font-family: var(--f-head);
    font-size: var(--t-3xl);
    font-weight: 900;
    line-height: 1;
    color: var(--c-ink);
    margin-bottom: var(--s-1);
}

.plan__per {
    font-size: var(--t-sm);
    color: var(--c-muted);
    margin-bottom: var(--s-6);
}

.plan__features {
    display: grid;
    gap: var(--s-3);
    margin-bottom: var(--s-7);
    font-size: var(--t-base);
}

.plan__features li {
    display: flex;
    gap: var(--s-3);
    align-items: flex-start;
}

.plan__features svg {
    flex: none;
    width: 18px;
    height: 18px;
    margin-top: 3px;
    color: var(--c-primary);
}

.plan__note {
    font-size: var(--t-base);
    color: var(--c-muted);
    margin-bottom: var(--s-7);
}

.plan .btn { margin-top: auto; }


/* ===================================================================
 * # download
 * ------------------------------------------------------------------- */

.s-download { background-color: var(--c-surface-warm); }

.download-cta { text-align: center; }

.badge-play {
    display: inline-block;
    line-height: 0;
    transition: transform .2s var(--ease), opacity .2s var(--ease);
}

.badge-play:hover { transform: translateY(-2px); }

.badge-play img { width: 200px; height: auto; }

.download-note {
    max-width: 46ch;
    margin: var(--s-5) auto 0;
    font-size: var(--t-sm);
    color: var(--c-muted);
}

.download-shot {
    margin-top: var(--s-10);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow-lg);
}


/* ===================================================================
 * # footer
 * ------------------------------------------------------------------- */

.site-footer {
    padding-block: var(--s-10) var(--s-6);
    background-color: var(--c-dark);
    color: var(--c-on-dark-muted);
    font-size: var(--t-base);
}

.site-footer h4 {
    font-size: var(--t-sm);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--c-on-dark);
    margin-bottom: var(--s-4);
}

.site-footer a { color: var(--c-on-dark-muted); }
.site-footer a:hover { color: var(--c-accent); }

.footer-grid {
    display: grid;
    gap: var(--s-8);
}

@media (min-width: 700px) {
    .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; }
}

.footer-links { display: grid; gap: var(--s-2); }

.footer-social {
    display: flex;
    gap: var(--s-3);
    margin-top: var(--s-5);
}

.footer-social a {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    border: 1px solid rgba(244, 239, 234, .18);
    border-radius: var(--radius-pill);
}

.footer-social a:hover {
    border-color: var(--c-accent);
    color: var(--c-accent);
}

.footer-social svg { width: 18px; height: 18px; }

.footer-bottom {
    margin-top: var(--s-9);
    padding-top: var(--s-5);
    border-top: 1px solid rgba(244, 239, 234, .12);
    font-size: var(--t-xs);
    color: var(--c-on-dark-muted);
}


/* ===================================================================
 * # back to top
 * ------------------------------------------------------------------- */

.site-footer a.to-top {
    position: fixed;
    right: var(--s-5);
    bottom: var(--s-5);
    z-index: 40;
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border-radius: var(--radius-pill);
    background-color: var(--c-primary);
    color: #fff;
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px);
    transition: opacity .22s var(--ease), transform .22s var(--ease), visibility .22s;
}

.site-footer a.to-top.is-visible { opacity: 1; visibility: visible; transform: none; }
.site-footer a.to-top:hover { background-color: var(--c-primary-hover); color: #fff; }
.site-footer a.to-top svg { width: 18px; height: 18px; }


/* ===================================================================
 * # language switch
 * ------------------------------------------------------------------- */

/* Every selector in this section is qualified with `.site-footer a`, and
   that is load-bearing rather than decorative: both floating controls are
   anchors inside the footer, where `.site-footer a` sets a muted cream at
   62% alpha. At 0,2,0 that beats a bare `.lang-switch` (0,1,0), so the
   colours declared below were silently discarded and the tab rendered pale
   text on a pale ground. `.to-top` had the same bug from the day it was
   written -- its `color: #fff` never once applied.

   A tab pinned to the right edge at mid height, deliberately clear of
   .to-top. That one sits in the bottom-right corner and fades in on
   scroll, so anything stacked above it would hang orphaned in the air
   for as long as it stayed hidden.

   It shows the language you would switch TO, not the one you are
   reading: a vertical tab has no room for two states, and "EN" reads as
   an action where "ES / EN" reads as a label.

   The markup lives inside the footer, and that is the whole reason it
   reaches the other three pages -- tools/_chrome.py lifts the footer out
   of index.html, exactly as it already does for .to-top. */
.site-footer a.lang-switch {
    position: fixed;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    /* above .to-top (40) and below the header (50), so the mobile
       drop-down panel covers it instead of fighting it */
    z-index: 45;
    /* Globe over code, stacked: the tab is a narrow vertical strip, so the
       two do not fit side by side without pushing it over the content. The
       icon says "language" -- a flag would say "country", which is a
       different claim and a wrong one (English is not the United States,
       and the reader this page is for is most likely in Colombia). */
    display: grid;
    justify-items: center;
    align-content: center;
    gap: var(--s-1);
    min-width: 44px;
    min-height: 44px;
    /* Optical centring, and the asymmetry is deliberate -- do not "tidy" it
       back to a single value.

       The left edge is a half-round: 999px clamps to half the height (~34px)
       on a box only 44px wide, so the curve eats most of the width and is
       still bending inward at the height of the icon. Geometrically centred
       content therefore READS as pushed left. Measured on the rendered page,
       ground to the left of each child against ground to its right:

           globe   11.3px / 14.5px    3.2px out
           text     9.7px / 11.1px    1.4px out

       Extra padding on the left moves the content box's centre right, and each
       1px of shift takes 2px off the imbalance. The two children sit at
       different heights, so no single value zeroes both -- 1.6px would centre
       the globe and leave the text 1.8px out, 0.7px would do the reverse. 1px
       of shift (2px of padding) splits it: +1.2 and -0.6, both under a pixel
       and a half and neither visible. Overshooting is worse than undershooting
       here; 4px of padding was tried and pushed the text visibly right.

       A smaller radius would remove the cause instead of correcting for it,
       but the round tab is the shape this site wants -- it echoes .to-top,
       which is a full circle. */
    padding: var(--s-3) var(--s-2) var(--s-3) calc(var(--s-2) + 2px);
    border-radius: var(--radius-pill) 0 0 var(--radius-pill);
    /* Not --c-primary. This tab is fixed, so it crosses the dark hero and
       the white sections below it without ever getting to pick one -- and
       the primary is the colour that fails on dark grounds, which is what
       --c-accent exists for. Tan with ink on top holds up over both. */
    background-color: var(--c-accent);
    color: var(--c-ink);
    font-family: var(--f-head);
    font-size: var(--t-xs);
    font-weight: 700;
    letter-spacing: .04em;
    box-shadow: var(--shadow-md);
    transition: background-color .22s var(--ease);
}

/* Inverts to the primary on hover: a clear state change that introduces
   no colour of its own. */
.site-footer a.lang-switch svg { width: 15px; height: 15px; }

.site-footer a.lang-switch:hover { background-color: var(--c-primary); color: #fff; }

/* Below the nav breakpoint the page is too narrow for a 44px tab to stay
   off the text -- worst on faq.html, which is 68 answers of running copy.
   Narrowed to roughly the width of the gutter it overlaps the padding and
   little else. The height stays at 44px so the tap target survives the
   trade; only the width gives way. */
@media (max-width: 900px) {
    .site-footer a.lang-switch {
        min-width: 36px;
        /* Same optical nudge, halved for the smaller tab. */
        padding: var(--s-2) var(--s-1) var(--s-2) calc(var(--s-1) + 2px);
    }

    .site-footer a.lang-switch svg { width: 13px; height: 13px; }
}


/* ===================================================================
 * # faq page
 * ------------------------------------------------------------------- */

/* faq.html and the legal page have no hero, so their first section has to
   clear the fixed header on its own. */
.page-inner .section:first-of-type { padding-top: calc(var(--header-h) + var(--s-9)); }

.faq-search {
    max-width: 520px;
    margin: 0 auto var(--s-6);
}

.faq-search input {
    width: 100%;
    padding: var(--s-3) var(--s-5);
    border: 1px solid var(--c-line);
    border-radius: var(--radius-pill);
    background-color: var(--c-surface);
    font: inherit;
    color: var(--c-ink);
}

.faq-search input::placeholder { color: var(--c-muted); }

.faq-search input:focus-visible {
    border-color: var(--c-primary);
    outline-offset: 0;
}

.faq-index {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s-2);
    margin-bottom: var(--s-6);
}

.faq-index a {
    display: inline-block;
    padding: var(--s-2) var(--s-4);
    border: 1px solid var(--c-line);
    border-radius: var(--radius-pill);
    font-size: var(--t-sm);
    color: var(--c-body);
}

.faq-index a:hover { border-color: var(--c-primary); color: var(--c-primary); }

.faq-index a.is-active {
    background-color: var(--c-primary);
    border-color: var(--c-primary);
    color: #fff;
}

.faq-status {
    min-height: 1.5em;
    margin-bottom: var(--s-6);
    text-align: center;
    font-size: var(--t-sm);
    color: var(--c-muted);
}

.faq-group { margin-bottom: var(--s-9); }
.faq-group:last-child { margin-bottom: 0; }

.faq-group > h2 {
    font-size: var(--t-xl);
    padding-bottom: var(--s-3);
    margin-bottom: var(--s-5);
    border-bottom: 2px solid var(--c-primary);
}

.faq-item {
    padding-block: var(--s-5);
    border-bottom: 1px solid var(--c-line);
    scroll-margin-top: calc(var(--header-h) + var(--s-5));
}

.faq-item:first-child { padding-top: 0; }

.faq-item h3 {
    font-size: var(--t-base);
    margin-bottom: var(--s-2);
}

.faq-item p { font-size: var(--t-base); }
.faq-item p:last-child { margin-bottom: 0; }

.faq-item.is-hidden,
.faq-group.is-hidden { display: none; }

.faq-wrap { max-width: 860px; margin-inline: auto; }


/* ===================================================================
 * # legal page
 * ------------------------------------------------------------------- */

.legal-updated {
    margin-top: var(--s-4);
    font-size: var(--t-sm);
    color: var(--c-muted);
}

.legal-toc {
    max-width: 860px;
    margin: 0 auto var(--s-9);
    padding-bottom: var(--s-6);
    border-bottom: 1px solid var(--c-line);
}

.legal-toc ul {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s-2);
}

.legal-toc a {
    display: inline-block;
    padding: var(--s-2) var(--s-4);
    border: 1px solid var(--c-line);
    border-radius: var(--radius-pill);
    font-size: var(--t-sm);
    color: var(--c-body);
}

.legal-toc a:hover { border-color: var(--c-primary); color: var(--c-primary); }

.legal-doc {
    max-width: 800px;
    margin: 0 auto var(--s-11);
    scroll-margin-top: calc(var(--header-h) + var(--s-5));
}

.legal-doc:last-child { margin-bottom: 0; }

.legal-doc__title {
    font-size: var(--t-2xl);
    padding-bottom: var(--s-3);
    margin-bottom: var(--s-5);
    border-bottom: 2px solid var(--c-primary);
}

.legal-lead {
    font-size: var(--t-lg);
    color: var(--c-muted);
    margin-bottom: var(--s-7);
}

.legal-doc h3 {
    margin-top: var(--s-8);
    margin-bottom: var(--s-3);
    font-size: var(--t-lg);
}

.legal-doc h4 {
    margin-top: var(--s-5);
    margin-bottom: var(--s-2);
    font-size: var(--t-base);
    color: var(--c-primary);
}

.legal-doc p,
.legal-doc ul { margin-bottom: var(--s-4); }

.legal-doc ul { padding-left: var(--s-5); }

.legal-doc li {
    list-style: disc;
    margin-bottom: var(--s-2);
}

/* who the responsable del tratamiento is -- required by Ley 1581 de 2012.
   Sits before clause 1 and is deliberately unnumbered, so the cross
   references to "1.c" elsewhere keep pointing at the same clause. */
.legal-responsible {
    margin-bottom: var(--s-7);
    padding: var(--s-5) var(--s-6);
    border-left: 3px solid var(--c-primary);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    background-color: var(--c-surface-warm);
}

.legal-responsible__label {
    margin-bottom: var(--s-1);
    font-family: var(--f-head);
    font-size: var(--t-xs);
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--c-primary);
}

.legal-responsible__name {
    margin-bottom: var(--s-3);
    font-family: var(--f-head);
    font-size: var(--t-lg);
    font-weight: 700;
    color: var(--c-ink);
}

.legal-doc .legal-responsible__data {
    margin-bottom: var(--s-3);
    padding-left: 0;
}

.legal-doc .legal-responsible__data li { list-style: none; }

.legal-doc .legal-responsible__note {
    margin-bottom: 0;
    font-size: var(--t-sm);
    color: var(--c-muted);
}


/* ===================================================================
 * # 404
 * ------------------------------------------------------------------- */

.s-404 {
    display: grid;
    place-items: center;
    min-height: 70svh;
    text-align: center;
}

.s-404 p { max-width: 46ch; margin-inline: auto; color: var(--c-muted); }
