/* borsa.css — El món visual de la part pública de la Borsa d'habitatges.
 *
 * ── Què és i per què està acotat ───────────────────────────────────────────
 *
 * Tot penja de `.borsa`, el <div> que embolcalla el contingut dins del chrome
 * oficial de la UPC. No és manieta: el tema de genweb6 porta el seu propi
 * Bootstrap amb regles per a `.card`, `.btn` i companyia, i unes regles
 * nostres sense acotar competirien a tota la pàgina, capçalera i peu inclosos,
 * que no són nostres.
 *
 * El chrome ocupa entre el 58 % i el 92 % de cada pàgina. Això vol dir que el
 * que fem aquí és una minoria de la superfície, i per tant ha de ser
 * NÍTIDAMENT més tranquil que el seu marc, no competir-hi.
 *
 * ── La idea ────────────────────────────────────────────────────────────────
 *
 * Cada oferta és un mòdul complet en si mateix que, al costat dels altres,
 * forma UN SOL CAMP continu: la disciplina del paviment hidràulic, on cada
 * rajola es basta sola i quatre juntes fan una rosassa. Per això els mòduls
 * es toquen —els separa un filet, no un buit— i el conjunt té una vora i un
 * radi, no cada peça el seu.
 *
 * L'alternativa, la graella de targetes flotants amb ombra, és el que envia
 * aquesta categoria; amb catorze ofertes i CAP FOTOGRAFIA només subratlla el
 * que no hi ha.
 *
 * ── Els colors no es declaren aquí ─────────────────────────────────────────
 *
 * `--upc-primary`, `--upc-secondary` i `--upc-accent` arriben a l'atribut
 * `style` del `.borsa` des de les constants `COLOR_*` de `config/config.php`.
 * Escriure'ls aquí faria dues llistes de colors corporatius i el dia que la
 * UPC en canviés un, aquesta es quedaria enrere.
 *
 * El blau d'acció ÉS el blau corporatiu. No se n'hi afegeix un de propi:
 * dues blaus a la mateixa pàgina és un error, no una paleta.
 *
 * ── Contrast ───────────────────────────────────────────────────────────────
 *
 * WCAG 2.1 AA és obligatori (RD 1112/2018, EN 301 549). Mesurat, no estimat:
 *
 *     #1d1d1f sobre #ffffff   16,1:1
 *     #6e6e73 sobre #ffffff    5,1:1
 *     #6e6e73 sobre #f5f5f7    4,7:1
 *     #007BC0 sobre #ffffff    4,6:1
 *     #ffffff sobre #007BC0    4,6:1
 *     #005A8E sobre #ffffff    7,4:1
 *
 * El gris secundari d'Apple (#86868b, 3,6:1) NO es pot fer servir. És el
 * primer que es copia d'aquell llenguatge i el primer que no passa.
 */

/* ═══ Tokens ════════════════════════════════════════════════════════════════
   Viuen a `.borsa` i no a `:root` perquè el chrome de la UPC té el seu propi
   joc i no s'han de barrejar. */

.borsa {
    --b-ground:   #ffffff;
    --b-field:    #f5f5f7;   /* el camp tintat, per separar seccions sense vores */
    --b-ink:      #1d1d1f;
    --b-ink-2:    #6e6e73;
    --b-line:     rgba(0, 0, 0, .10);
    --b-line-2:   rgba(0, 0, 0, .06);

    /* Un sol radi gran per als mòduls i un de petit per als controls. Dos
       valors, no cinc: una escala de radis que ningú pot recordar acaba
       aplicada a l'atzar. */
    --b-radius:    18px;
    --b-radius-sm: 12px;

    /* L'escala vertical. Potències de 4 perquè caiguin sobre la graella de
       Bootstrap que el chrome ja imposa. */
    --b-1: .25rem;
    --b-2: .5rem;
    --b-3: .75rem;
    --b-4: 1rem;
    --b-6: 1.5rem;
    --b-8: 2rem;
    --b-12: 3rem;

    /* L'EASING QUE FAN SERVIR ELLS. Mesurat als seus fulls d'estil:
       `cubic-bezier(.4,0,.6,1)` surt deu vegades, més que cap altre. */
    --b-ease: cubic-bezier(.4, 0, .6, 1);

    /* ── L'escala tipogràfica, llegida de store.apple.com ──────────────────
       Les seves mides no són fluides: són una llista discreta
       —12, 14, 17, 19, 21, 24, 28, 32, 40, 48, 64 px— que salta als
       breakpoints. Un `clamp()` dona mides intermitges que ells no fan
       servir mai, i és el que delatava la imitació.

       Van en `rem` i no en `px`: a 1rem = 16px donen la mateixa xifra que
       ells, però respecten la mida de lletra que l'usuari hagi posat al
       navegador, que és una ajuda real per a qui hi veu poc. */
    --b-t12: .75rem;
    --b-t14: .875rem;
    --b-t17: 1.0625rem;   /* el cos */
    --b-t21: 1.3125rem;
    --b-t24: 1.5rem;
    --b-t28: 1.75rem;
    --b-t32: 2rem;
    --b-t40: 2.5rem;

    /* El seu interlineat de cos: 25/17. I el seu tracking, -.022em, que és
       el valor que més surt als seus fulls després de -.016em. */
    --b-lh:  1.47059;
    --b-ls:  -.022em;

    color: var(--b-ink);
    font-size: var(--b-t17);
    line-height: var(--b-lh);
    letter-spacing: var(--b-ls);
    font-weight: 400;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* ── La pila tipogràfica ───────────────────────────────────────────────────
 *
 * La seva, llegida de store.apple.com, és:
 *
 *     SF Pro Display, SF Pro Icons, Helvetica Neue, Helvetica, Arial
 *
 * Aquesta és la mateixa cadena amb `-apple-system` al davant, que és com un
 * tercer pot demanar SF Pro sense servir-la: la font està llicenciada per a
 * plataformes Apple i no es pot allotjar aquí. A Mac i a iPhone surt SF Pro
 * de debò; a la resta, Helvetica Neue o Arial, exactament com els passa a
 * ells.
 *
 * NO hi ha ni Segoe UI ni Roboto, i és una decisió conscient: donarien la
 * cara nativa de Windows i d'Android, que es llegeix millor però canvia la
 * forma de la pàgina segons l'aparell. Ells accepten aquest canvi i nosaltres
 * també, perquè el que s'ha demanat és acostar-s'hi.
 *
 * Cap font externa, i per tant cap canvi a la Content-Security-Policy:
 * afegir-hi un origen és una decisió, no un detall d'implementació. */
.borsa,
.borsa .form-control,
.borsa .form-select,
.borsa .btn {
    font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display",
                 "Helvetica Neue", Helvetica, Arial, sans-serif;
}

/* ═══ Les superfícies que no hem dibuixat ═══════════════════════════════════
   Selecció, cursor, anell de focus, barres de desplaçament i xifres. Vénen
   amb el valor per defecte del navegador, que no és de cap sistema de
   disseny. És el senyal més barat que una pàgina s'ha fet i no s'ha muntat,
   i el que més es queda sense fer. */

.borsa ::selection {
    background: rgba(0, 123, 192, .18);   /* els navegadors sense color-mix */
    background: color-mix(in srgb, var(--upc-primary) 18%, transparent);
    color: var(--b-ink);
}
.borsa { caret-color: var(--upc-primary); }

/* Un sol anell de focus a tota la part pública, visible sobre qualsevol fons
   i mai amagat: és l'única manera d'orientar-se amb teclat. */
.borsa :focus-visible {
    outline: 2px solid var(--upc-primary);
    outline-offset: 2px;
    border-radius: var(--b-radius-sm);
}
.borsa :focus:not(:focus-visible) { outline: none; }

.borsa * {
    scrollbar-width: thin;
    scrollbar-color: var(--b-line) transparent;
}
.borsa *::-webkit-scrollbar { width: 10px; height: 10px; }
.borsa *::-webkit-scrollbar-thumb {
    background: var(--b-line);
    border-radius: 99px;
    border: 3px solid transparent;
    background-clip: content-box;
}

/* Xifres tabulars a tot el que és quantitat: preus, metres, habitacions i
   dates. Sense això les columnes ballen quan canvia una xifra. */
.borsa .preu,
.borsa .modul__dades,
.borsa .codi-gran,
.borsa time { font-variant-numeric: tabular-nums; }

/* ═══ Tipografia ════════════════════════════════════════════════════════════
   Escala curta i passos evidents. El chrome ja posa l'<h1>; aquí comencem a
   l'<h2>. */

.borsa h2 {
    font-size: var(--b-t24);
    font-weight: 600;
    letter-spacing: -.016em;      /* el tracking que més fan servir */
    line-height: 1.16667;         /* 28/24 */
    margin-bottom: var(--b-2);
}
@media (min-width: 1024px) { .borsa h2 { font-size: var(--b-t32); line-height: 1.125; } }

.borsa h3 {
    font-size: var(--b-t21);
    font-weight: 600;
    letter-spacing: -.016em;
    line-height: 1.19048;         /* 25/21 */
}
.borsa h4 {
    font-size: var(--b-t17);
    font-weight: 600;
    letter-spacing: var(--b-ls);
    line-height: 1.23529;
}

/* Més aire a sobre d'un títol que a sota: el que l'enganxa al que ve
   després és el que el fa llegir com a títol d'allò.

   El títol d'una targeta en queda FORA, i el motiu val la pena escriure'l
   perquè va costar de veure: aquesta regla només salta quan el títol no és
   el primer fill, i dins d'una targeta això passa exactament quan hi ha
   l'etiqueta «NOU» al davant. Les targetes amb NOU duien el títol 32px
   més avall que les altres, descolocat respecte de la creu.
   
   `:not(:first-child)` suma l'especificitat del seu argument, de manera que
   `.borsa h3:not(:first-child)` (0,2,1) guanyava a `.borsa .modul__titol`
   (0,2,0) i el `margin: 0` del títol no servia de res. */
.borsa h2:not(:first-child),
.borsa h3:not(.modul__titol):not(:first-child) { margin-top: var(--b-8); }

.borsa p { line-height: var(--b-lh); }

/* La mesura del text llarg. Sense això, a l'escriptori la descripció d'una
   oferta arriba als 140 caràcters per línia i es perd el fil en tornar. */
.borsa .text-llarg { max-width: 68ch; }

.borsa .text-muted { color: var(--b-ink-2) !important; }

/* ── L'entradeta del llistat ───────────────────────────────────────────────
 *
 * La frase que hi ha sota el títol de la portada: diu on és la persona i
 * quines són les dues opcions d'allotjament.
 *
 * Va a 21px i no a la mida del cos perquè és el primer text de la pàgina i
 * ha de guanyar el pes que les targetes de sota li prenen; i amb la mesura
 * acotada, perquè a l'escriptori una línia de 140 caràcters fa perdre el fil
 * just on es decideix si val la pena quedar-s'hi.
 *
 * Hi havia una segona frase, l'avís que l'escola només difon. Es va treure
 * el 2026-10-10: el llistat ja el porta al peu i la fitxa de cada oferta el
 * repeteix a la capsa de contacte, de manera que dir-ho també aquí era la
 * tercera vegada a la mateixa pantalla. */
.borsa .entrada {
    font-size: var(--b-t21);
    line-height: 1.381;
    letter-spacing: -.021em;
    color: var(--b-ink);
    max-width: 68ch;

    /* 2rem per sobre i 2rem per sota: el mateix aire fins al titular que
       fins als botons.

       A dalt el valor real el decideix el col·lapse de marges. El `<h1>`
       és del chrome i no és fill de `.borsa`, però `.borsa` no té ni
       `padding` ni vora, de manera que el marge superior d'aquest paràgraf
       surt a fora i es troba amb el de l'`<h1>`: queda el més gran dels
       dos. Al tema de la UPC l'`<h1>` porta `margin-bottom: 1rem`
       —mesurat a `theme.min.css`, no suposat—, i per tant guanya aquest 2rem.
       Si algun dia la UPC el puja per sobre de 2rem, aquest valor deixarà
       de manar i el buit creixerà: no es pot evitar des d'aquí sense tocar
       una regla del chrome, que no és nostra. */
    margin: var(--b-8) 0;
}
/* L'enllaç de la Residència no porta regla pròpia: el de més avall
   (`.borsa a:not(.btn):not(.modul)`) ja el pinta amb el blau corporatiu. */

/* ═══ El camp i els mòduls ══════════════════════════════════════════════════
   LA PEÇA DE LA CASA. Els mòduls es toquen; el que els separa és un filet
   d'un píxel, no un buit. La vora i el radi són del CAMP, no de cada peça,
   de manera que el conjunt es llegeix com una sola superfície. */

/* El seu patró, mesurat als seus fulls: `background:#fff; border-radius:18px`
   sobre un fons `#f5f5f7` (23 aparicions), separades per un buit.
   Targetes soltes, doncs, i no el paviment continu que hi havia abans.

   El canvi arregla de passada un defecte que només es veia a la pantalla:
   amb `overflow: hidden` al contenidor, l'anell de focus del teclat quedava
   TALLAT a la vora de la targeta i es llegia com una ratlla blava
   inexplicable. Sense contenidor retallat, l'anell es dibuixa sencer. */
.borsa .camp {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
    background: var(--b-field);
    border-radius: 24px;           /* el de fora, més gran que el de dins */
    padding: 16px;
}

@media (min-width: 768px) {
    .borsa .camp {
        grid-template-columns: repeat(2, 1fr);
        gap: 20px;
        padding: 20px;
    }
}
@media (min-width: 1200px) { .borsa .camp { grid-template-columns: repeat(3, 1fr); } }

.borsa .modul {
    position: relative;       /* el marc de «NOU» */
    display: flex;
    flex-direction: column;
    gap: var(--b-2);
    padding: 24px;
    background: var(--b-ground);
    border-radius: var(--b-radius);   /* 18px, el seu valor més usat */
}

/* L'únic moment de moviment de la pàgina. L'ombra és la seva, llegida dels
   seus fulls: `2px 4px 12px #00000014` porta desplaçament EN LES DUES
   DIRECCIONS i una difuminació ampla; un halo centrat sense desplaçament és
   decoració, no profunditat.

   Va a la CAIXA i no a l'enllaç. La creu està posicionada sobre la caixa,
   de manera que movent només l'enllaç la targeta s'aixecava i la creu es
   quedava clavada al seu lloc.

   `:focus-within` i no `:focus-visible`: el focus pot anar a l'enllaç o a la
   creu, i la targeta ha de respondre tant si ve l'un com l'altre. */
.borsa a.modul { text-decoration: none; color: inherit; display: flex; }

.borsa .modul-caixa {
    transition: box-shadow .3s var(--b-ease), transform .3s var(--b-ease);
}
.borsa .modul-caixa:hover,
.borsa .modul-caixa:focus-within {
    box-shadow: 2px 4px 12px rgba(0, 0, 0, .08),
                2px 4px 16px rgba(0, 0, 0, .06);
    transform: translateY(-2px);
    border-radius: var(--b-radius);
}

/* ── La caixa d'un mòdul ───────────────────────────────────────────────────
 *
 * El mòdul és un enllaç sencer, i el botó de tancar NO pot anar-hi a dins:
 * un `<button>` dins d'un `<a>` és HTML invàlid i cada navegador ho resol
 * com li sembla. Per això hi ha una caixa que els conté tots dos: l'enllaç
 * omple la caixa i el botó se superposa a la cantonada.
 */
.borsa .modul-caixa {
    position: relative;
    display: flex;
}
.borsa .modul-caixa > .modul { flex: 1 1 auto; }
.borsa .modul-caixa[hidden] { display: none; }

/* ── El botó de tancar ─────────────────────────────────────────────────────
 *
 * Només surt si hi ha JavaScript: sense ell no faria res, i un control que
 * no fa res és pitjor que no tenir-lo. La classe `js` la posa l'script de
 * baix de tot de la pàgina.
 *
 * 44×44 és la zona de toc; la creu dibuixada n'ocupa 28. Un objectiu de 28
 * píxels al mòbil es falla més que no s'encerta.
 */
.borsa .tanca { display: none; }

.js .borsa .tanca {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    /* Centrat amb la PRIMERA LÍNIA del títol, no amb la vora de la targeta.
       El títol comença a 24px (el coixinet) i la seva línia fa 28px
       (24px × 1,16667), de manera que el seu centre cau a 38px; el cercle
       fa 48 d'alçada i per tant comença a 38 − 24 = 14.
       Si algun dia canvia la mida del títol, aquest número canvia amb ell. */
    top: 14px;
    right: 8px;
    width: 48px;
    height: 48px;
    padding: 0;
    border: 0;
    border-radius: 980px;
    background: transparent;
    color: var(--b-ink-2);
    font-size: 30px;          /* el doble que abans */
    line-height: 1;
    cursor: pointer;
    opacity: .55;
    transition: opacity .2s var(--b-ease), background-color .2s var(--b-ease);
}
.borsa .tanca:hover,
.borsa .tanca:focus-visible {
    opacity: 1;
    background: var(--b-field);
    color: var(--b-ink);
}

/* ── «NOU» ─────────────────────────────────────────────────────────────────
 *
 * Només els primers 14 dies, i va a sota de la creu. Es posiciona respecte
 * del mòdul i no de la caixa perquè és contingut de l'oferta: ha de quedar
 * DINS de l'enllaç perquè qui el llegeix amb un lector de pantalla sent
 * «NOU» com a part del que clica, no com una etiqueta solta de la pàgina.
 *
 * Blanc sobre el rovell: 5,50:1. */
.borsa .modul__nou {
    position: absolute;
    top: 66px;                /* just sota la creu: 14 + 48 + 4 */
    right: 14px;
    display: inline-flex;
    padding: .2rem .55rem;
    border-radius: 980px;
    background: #b64400;
    color: #fff;
    font-size: var(--b-t12);
    font-weight: 600;
    letter-spacing: .02em;
    line-height: 1.33;
}

/* La creu i el «NOU» ocupen la cantonada de dalt a la dreta. El títol i la
   població són els dos únics elements que cauen a la seva alçada, i sense
   aquest reservat una línia llarga els passava per sota.

   És un defecte que ja hi era amb la creu petita i que no es veia perquè
   els títols de prova eren curts. */
.borsa .modul__titol,
.borsa .modul__lloc { padding-right: 56px; }

/* ── El peu de la targeta: tipus a l'esquerra, data a la dreta ─────────── */
/* `margin-top: auto` és el que clava el peu a baix de tot sigui quin sigui
   el contingut de sobre; com que la graella fa totes les targetes d'una
   fila igual d'altes, les dues píndoles queden alineades entre targetes. */
.borsa .modul__peu {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--b-2);
    margin: auto 0 0;
    padding-top: var(--b-3);
}
/* La data porta la classe `etiqueta` al marcat, de manera que és la mateixa
   píndola que el tipus d'habitatge i no una variant que se'n separa el dia
   que algu toqui l'una i no l'altra. */
.borsa .modul__data { white-space: nowrap; }

/* ── El control per tornar-les a mostrar ──────────────────────────────────
 *
 * Només existeix si JavaScript hi és i si hi ha alguna oferta amagada: un
 * interruptor que no pot fer res no ha de ser a la pantalla. */
.borsa .restaura { display: none; }
.borsa .restaura.hi-som {
    display: flex;
    align-items: center;
    gap: var(--b-2);
    margin: var(--b-3) 0 0;
    font-size: var(--b-t14);
    letter-spacing: -.016em;
    color: var(--b-ink-2);
}
.borsa .restaura .form-check-input { margin: 0; cursor: pointer; }
.borsa .restaura label { cursor: pointer; }

/* Quan s'han amagat totes. */
.borsa .totes-amagades {
    display: none;
    margin: 0;
    padding: var(--b-8) var(--b-6);
    text-align: center;
    color: var(--b-ink-2);
}
.borsa .totes-amagades.hi-som { display: block; }

/* ── El preu ───────────────────────────────────────────────────────────────
   Amb catorze ofertes i cap fotografia, el preu és l'únic element que pot
   carregar el pes visual. Al mòbil puja a escala monumental; és el que
   permet escanejar la llista amb el polze sense llegir res més. *//* ── El preu ───────────────────────────────────────────────────────────────
 *
 * Va a la mida del cos i en gris. Fins al 2026-10-09 era de 32px i manava
 * la targeta; l'escola va decidir que el que s'ha de llegir primer és QUÈ
 * és l'habitatge, no quant costa.
 *
 * No desapareix: la xifra es queda en negre i en pes 600 dins d'una línia
 * gris, de manera que encara s'escaneja la columna de preus d'una ullada
 * sense que cridi per damunt del títol. */
.borsa .preu {
    font-size: var(--b-t17);
    font-weight: 400;
    letter-spacing: var(--b-ls);
    line-height: var(--b-lh);
    color: var(--b-ink-2);
}
.borsa .preu strong {
    font-weight: 600;
    color: var(--b-ink);
}
.borsa .preu__mes {
    font-size: var(--b-t17);
    font-weight: 400;
    letter-spacing: var(--b-ls);
    color: var(--b-ink-2);
}

.borsa .modul__titol {
    font-size: var(--b-t24);
    font-weight: 600;             /* ells no fan servir el 500 enlloc */
    letter-spacing: -.016em;
    line-height: 1.16667;         /* 28/24 */
    margin: 0;
}

/* ── El color del títol, segons el tipus d'habitatge ───────────────────────
 *
 * El degradat recorre el títol d'un to a l'altre, com fan ells a les
 * targetes de la botiga.
 *
 * DUES COSES QUE EL FAN LEGIBLE, i cap de les dues és opcional:
 *
 * 1. El color pla va PRIMER. Si el navegador no sap retallar el fons al
 *    text, es queda amb aquest; sense la primera declaració, un navegador
 *    antic ensenyaria un títol transparent, és a dir cap títol.
 *
 * 2. Els DOS extrems passen AA per separat, mesurats sobre la targeta
 *    blanca. Quan el color del text canvia al llarg de la línia no n'hi ha
 *    prou de mirar-ne un:
 *
 *        #b64400  5,50:1      #a5247c  6,68:1
 *        #7230c1  7,22:1      #005A8E  7,36:1
 *        #0b6b3a  6,61:1      #6b6410  6,08:1
 *
 * El degradat ocupa l'amplada de la targeta i no la del text: dins d'una
 * columna flex el títol és un bloc i no se'n pot fer altrament. Per això un
 * títol curt ensenya sobretot el primer to i un de llarg recorre els dos.
 * És el comportament que es va triar veient-lo, no un descuit. */
.borsa .titol--pis_complet { color: #b64400; }
.borsa .titol--habitacio   { color: #7230c1; }
.borsa .titol--estudi      { color: #0b6b3a; }
.borsa .titol--duplex      { color: #a5247c; }
.borsa .titol--casa        { color: #6b6410; }

/* Els mateixos cinc degradats, posats als titulars de les seccions del
   formulari públic. Són les mateixes parelles i no unes de noves: el
   formulari i el llistat són la mateixa borsa, i inventar-hi una segona
   família de colors hauria volgut dir mesurar-ne el contrast una altra
   vegada per guanyar-hi res.

   COMPTE en afegir-ne un de nou: la regla de sota agafa QUALSEVOL classe que
   contingui «titol--» i li posa `color: transparent`. Una classe nova sense
   la seva línia de `background-image` no es queda sense degradat: es queda
   sense títol. */
.borsa .titol--sec-habitatge        { color: #b64400; }
.borsa .titol--sec-caracteristiques { color: #7230c1; }
.borsa .titol--sec-preu             { color: #0b6b3a; }
.borsa .titol--sec-dades            { color: #6b6410; }

@supports (background-clip: text) or (-webkit-background-clip: text) {
    .borsa [class*="titol--"] {
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
    }
    .borsa .titol--pis_complet { background-image: linear-gradient(100deg, #b64400, #a5247c); }
    .borsa .titol--habitacio   { background-image: linear-gradient(100deg, #7230c1, #005A8E); }
    .borsa .titol--estudi      { background-image: linear-gradient(100deg, #0b6b3a, #005A8E); }
    .borsa .titol--duplex      { background-image: linear-gradient(100deg, #a5247c, #7230c1); }
    .borsa .titol--casa        { background-image: linear-gradient(100deg, #6b6410, #b64400); }

    /* Aquí sí que va `inline-block`, i és l'única diferència amb les
       targetes. Un titular de secció és curt —«Què entra al preu»— i si el
       degradat ocupa l'amplada de la capçalera sencera, el text només
       n'agafa el primer pam i surt d'un color pla. Amb la caixa ajustada al
       text, el degradat es recorre sencer i es veu que n'és un. */
    .borsa [class*="titol--sec-"] { display: inline-block; }

    .borsa .titol--sec-habitatge        { background-image: linear-gradient(100deg, #b64400, #a5247c); }
    .borsa .titol--sec-caracteristiques { background-image: linear-gradient(100deg, #7230c1, #005A8E); }
    .borsa .titol--sec-preu             { background-image: linear-gradient(100deg, #0b6b3a, #005A8E); }
    .borsa .titol--sec-dades            { background-image: linear-gradient(100deg, #6b6410, #b64400); }
}
.borsa .modul__lloc {
    font-size: var(--b-t17);
    font-weight: 400;
    letter-spacing: var(--b-ls);
    color: var(--b-ink-2);
    margin: 0;
}

/* Les dades que hi ha: habitacions, banys, metres. Separades per un punt i
   no per icones, perquè una icona per cada xifra és soroll quan n'hi ha
   tres i la unitat ja ho diu. */
.borsa .modul__dades {
    font-size: var(--b-t14);
    letter-spacing: -.016em;
    color: var(--b-ink-2);
    margin: 0;
}
.borsa .modul__dades span + span::before {
    content: "·";
    margin: 0 .45em;
    color: var(--b-line);
}

/* ── L'etiqueta del tipus d'habitatge ──────────────────────────────────────
 *
 * GRISA. El color del tipus va al títol (vegeu `titol--*` més amunt), i
 * pintar també l'etiqueta seria dir dues vegades la mateixa cosa amb el
 * mateix color a quatre centímetres de distància.
 *
 * Tampoc no és blava, i per dues raons que coincideixen: el blau només
 * surt on es pot fer alguna cosa —una etiqueta blava semblaria un
 * enllaç— i, mesurat, el blau corporatiu sobre aquest fons dona 4,20:1 i
 * no passa AA. */
.borsa .etiqueta {
    display: inline-flex;
    align-items: center;
    gap: var(--b-1);
    padding: .25rem .6rem;
    font-size: var(--b-t12);
    font-weight: 400;
    letter-spacing: -.01em;
    color: var(--b-ink-2);
    background: var(--b-field);
    border-radius: 980px;
    white-space: nowrap;
}



/* ═══ Estats ════════════════════════════════════════════════════════════════
   Cap estat es diu NOMÉS amb color: tots porten icona i text. És el que els
   fa llegibles en blanc i negre, amb daltonisme i en un mòbil al sol. */

.borsa .estat {
    display: inline-flex;
    align-items: center;
    gap: var(--b-1);
    font-size: var(--b-t14);
    font-weight: 400;
    letter-spacing: -.016em;
}
.borsa .estat--sense { color: var(--b-ink-2); }
.borsa .estat--avis  { color: #8a5a00; }   /* 4,9:1 sobre blanc */

/* ── Què entra al preu i què no ───────────────────────────────────────────
 *
 * El color va NOMÉS a la icona; el titular es queda amb la tinta. Verd i
 * vermell a la vegada en dos titulars de la mateixa fila criden més que el
 * que diuen.
 *
 * Tenien `text-success` i `text-danger` de Bootstrap i sortien FOSQUES: el
 * tema de la UPC les pisa. D'aquí que vagin amb regla pròpia, que és a més
 * la norma de la casa —`.borsa` no depen de les utilitats d'un tema que no
 * és nostre.
 *
 * El color no és l'únic senyal: el titular ja diu «inclou» o «NO inclou»,
 * i les icones són un més i un menys, que es distingeixen sense color.
 *
 * **El que s'inclou va en gris fort i no en verd**, i la parella no és
 * simètrica a propòsit. El verd i el vermell de costat convertien dos
 * titulars veïns en un semàfor, i en una pàgina sense fotografies era el
 * que més cridava de tota la fitxa. El que s'inclou és el cas normal —la
 * majoria de les característiques d'una oferta són «sí»— i el normal no
 * necessita color: només el que s'EXCLOU val la pena que s'aturi l'ull.
 * El gris és #48484a i no la tinta #1d1d1f perquè la icona s'ha de llegir
 * com una marca i no com una paraula més del titular.
 *
 *     #48484a  9,12:1      #c01425  6,24:1   sobre la targeta blanca */
.borsa .icona--inclos { color: #48484a; }
.borsa .icona--exclos { color: #c01425; }
.borsa .icona--proces { color: #8a5a00; }   /* 5,9:1; el mateix de l'avís */

/* ── El preu de la fitxa ───────────────────────────────────────────────────
 *
 * Al llistat el preu és secundari: el que s'hi compara és QUÈ és cada
 * habitatge. A la fitxa ja s'ha triat l'oferta i la pregunta passa a ser
 * quant costa, així que recupera la mida gran que tenia al llistat. */
.borsa .preu--gran {
    font-size: var(--b-t32);
    line-height: 1.0625;
}
.borsa .preu--gran strong { letter-spacing: -.022em; }
.borsa .preu--gran .preu__mes { font-size: var(--b-t17); }

@media (min-width: 1024px) {
    .borsa .preu--gran { font-size: var(--b-t40); line-height: 1.05; }
}

/* ═══ Controls ══════════════════════════════════════════════════════════════
   El blau apareix NOMÉS on es pot fer alguna cosa. Res decoratiu és blau:
   és la regla que fa que, d'una ullada, se sàpiga què és prémer. */

.borsa .btn {
    border-radius: 980px;         /* el radi de píndola que fan servir ells */
    font-size: var(--b-t17);
    font-weight: 400;
    letter-spacing: -.022em;
    padding: .6rem 1.25rem;
    transition: background-color .2s var(--b-ease),
                border-color .2s var(--b-ease),
                color .2s var(--b-ease);
}

.borsa .btn-upc {
    background: var(--upc-primary);
    border-color: var(--upc-primary);
    color: #fff;
}
.borsa .btn-upc:hover,
.borsa .btn-upc:focus {
    background: var(--upc-secondary);
    border-color: var(--upc-secondary);
    color: #fff;
}

/* El secundari no porta color: no competeix amb l'acció principal. */
.borsa .btn-outline-secondary {
    border-color: var(--b-line);
    color: var(--b-ink);
    background: transparent;
}
.borsa .btn-outline-secondary:hover,
.borsa .btn-outline-secondary:focus {
    background: var(--b-field);
    border-color: var(--b-line);
    color: var(--b-ink);
}

.borsa a:not(.btn):not(.modul) {
    color: var(--upc-secondary);       /* 7,4:1: segur fins i tot a 13px */
    text-decoration-thickness: 1px;
    text-underline-offset: .18em;
}

/* ═══ Seccions ══════════════════════════════════════════════════════════════
   Un bloc tintat sense vora separa millor que una targeta amb ombra, i no
   introdueix una capa que no vol dir res. */

.borsa .bloc {
    background: var(--b-field);
    border-radius: var(--b-radius);
    padding: var(--b-6);
}

/* L'avís legal: ha de ser llegible, no decoratiu, i no ha de semblar una
   alerta d'error. */
.borsa .avis {
    font-size: var(--b-t14);
    letter-spacing: -.016em;
    color: var(--b-ink-2);
    line-height: 1.42857;         /* 20/14 */
    max-width: 68ch;
}
.borsa .avis strong { color: var(--b-ink); font-weight: 600; }

/* ═══ Formularis ════════════════════════════════════════════════════════════ */

.borsa .form-control,
.borsa .form-select {
    border-radius: 12px;          /* el radi de control que fan servir ells */
    border-color: var(--b-line);
    font-size: var(--b-t17);
    letter-spacing: var(--b-ls);
    padding: .6rem .85rem;
    color: var(--b-ink);
    background-color: var(--b-ground);
    transition: border-color .18s var(--b-ease), box-shadow .18s var(--b-ease);
}
.borsa .form-control:focus,
.borsa .form-select:focus {
    border-color: var(--upc-primary);
    box-shadow: 0 0 0 4px rgba(0, 123, 192, .14);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--upc-primary) 14%, transparent);
}
/* El text de marcador de posició també ha de passar AA: és text. */
.borsa .form-control::placeholder { color: var(--b-ink-2); opacity: 1; }

.borsa .form-label {
    font-size: var(--b-t14);
    font-weight: 400;
    letter-spacing: -.016em;
    color: var(--b-ink);
    margin-bottom: var(--b-1);
}
.borsa .form-text {
    font-size: var(--b-t12);
    letter-spacing: -.01em;
    color: var(--b-ink-2);
}

.borsa .form-check-input { border-color: var(--b-line); }
.borsa .form-check-input:checked {
    background-color: var(--upc-primary);
    border-color: var(--upc-primary);
}

/* ═══ El codi de 8 caràcters ════════════════════════════════════════════════
   És l'única credencial del propietari i es copia a mà d'una pantalla o es
   dicta per telèfon. Monoespaiat perquè és una QUANTITAT que s'ha de
   transcriure sense error, no per fer-lo semblar tècnic. */

.borsa .codi-gran {
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
    font-size: var(--b-t28);
    letter-spacing: .22em;
    font-weight: 600;
    color: var(--b-ink);
    line-height: 1.2;
    text-indent: .22em;   /* compensa l'espaiat de l'última lletra */
}
@media (min-width: 1024px) { .borsa .codi-gran { font-size: var(--b-t32); } }

/* ═══ La graella de característiques ════════════════════════════════════════
   Mateixa disciplina que el camp: cel·les que es toquen, filet entre elles,
   radi només al conjunt. */

/* Aquí el retall SÍ que hi ha de ser: és el que fa que els filets de les
   cel·les segueixin el radi. No hi ha res enfocable a dins —són etiquetes i
   valors, no controls—, de manera que no pot tallar cap anell de focus com
   passava al llistat. */
.borsa .graella {
    border: 1px solid var(--b-line);
    border-radius: var(--b-radius);
    overflow: hidden;
}
.borsa .graella .border-end { border-color: var(--b-line-2) !important; }
.borsa .graella .border-bottom { border-color: var(--b-line-2) !important; }

/* ═══ Moviment ══════════════════════════════════════════════════════════════
   Qui ha demanat menys moviment al sistema operatiu, no en rep. */

@media (prefers-reduced-motion: reduce) {
    .borsa *,
    .borsa *::before,
    .borsa *::after {
        transition-duration: .01ms !important;
        animation-duration: .01ms !important;
    }
}
