/* Bundled stylesheet — consolidates the cascade previously split across 19
   <link> tags into one request. Section order below is byte-identical to the
   old link order, so cascade/specificity outcomes are unchanged; each source
   file's original content is preserved verbatim inside its marker comment.
   Individual source files remain on disk (unreferenced) for reference/rollback. */

/* === city.css === */
/* Google Fonts moved to a <link rel="stylesheet"> in index.html's <head>
   (with preconnect) so the font CSS fetch starts in parallel with this
   file instead of waiting for it to download+parse first — @import here
   forced a serial waterfall (HTML -> bundle.css -> font CSS -> font files). */
:root{--ink:#06142a;--paper:#f5f2eb;--blue:#246cff;--line:rgba(6,20,42,.15);--muted:#667288}*{box-sizing:border-box}html{scroll-behavior:auto}body{margin:0;background:var(--paper);color:var(--ink);font-family:Manrope,Arial,sans-serif}.wrap{width:min(1180px,calc(100% - 72px));margin:auto}.topbar{height:82px;display:flex;align-items:center;justify-content:space-between;position:absolute;z-index:5;left:0;right:0;color:#fff}.brand{display:inline-flex;align-items:center;gap:10px;color:inherit;text-decoration:none;font-size:10px;font-weight:800;letter-spacing:.17em}.brand img{width:37px;height:37px;object-fit:contain;filter:brightness(0) invert(1)}nav{display:flex;align-items:center;gap:24px}nav a{color:inherit;text-decoration:none;font-size:12px;font-weight:700}.lang-button{border:1px solid rgba(255,255,255,.55);background:rgba(4,14,31,.25);color:#fff;border-radius:100px;padding:8px 11px;font:600 11px 'DM Mono';cursor:pointer}.hero{min-height:760px;position:relative;overflow:hidden;color:#fff;isolation:isolate}.city-visual,.city-image,.city-vignette{position:absolute;inset:0}.city-visual{z-index:-2;background:#0f4789}.city-image{width:100%;height:100%;object-fit:cover;object-position:center;animation:cityBreathe 18s ease-in-out infinite alternate}.city-image-night{opacity:0;transition:opacity 2s ease}.city-vignette{z-index:1;background:linear-gradient(90deg,rgba(3,13,28,.88) 0%,rgba(3,13,28,.61) 30%,rgba(3,13,28,.13) 63%,rgba(3,13,28,.25) 100%),linear-gradient(0deg,rgba(3,13,28,.52),transparent 40%);pointer-events:none}body[data-city-mode="night"] .city-image-night{opacity:1}body[data-city-mode="night"] .city-image-day{opacity:0}.hero-layout{min-height:700px;padding:160px 0 92px;display:flex;align-items:center;justify-content:space-between;gap:60px;position:relative;z-index:2}.hero-copy{max-width:625px}.eyebrow,.section-index,.footer-kicker{font:500 10px 'DM Mono';text-transform:uppercase;letter-spacing:.14em}.eyebrow{margin:0 0 22px;display:flex;align-items:center;gap:9px}.pulse,.signal{display:inline-block;width:7px;height:7px;border-radius:50%;background:#61dbff;box-shadow:0 0 0 5px rgba(97,219,255,.15);animation:pulse 1.8s infinite}.hero h1{font-size:clamp(54px,6.25vw,88px);letter-spacing:-.07em;line-height:.94;margin:0;font-weight:800}.hero h1 em,.world h2 em{font-family:'Playfair Display',serif;font-weight:600;letter-spacing:-.075em}.hero-lede{max-width:495px;color:rgba(255,255,255,.83);font-size:17px;line-height:1.65;margin:30px 0}.hero-actions{display:flex;flex-wrap:wrap;gap:12px}.button{border-radius:999px;min-height:52px;padding:0 19px;display:inline-flex;align-items:center;gap:18px;border:0;font:700 12px Manrope;cursor:pointer;text-decoration:none}.button-primary{background:#fff;color:var(--ink);box-shadow:0 8px 30px rgba(0,0,0,.16)}.button-primary b{font-size:18px}.button-quiet{background:rgba(255,255,255,.14);color:#fff;border:1px solid rgba(255,255,255,.3);backdrop-filter:blur(12px)}.mode-icon{font-size:18px}.system-card{width:275px;align-self:flex-end;margin-bottom:11px;padding:18px;background:rgba(4,15,32,.72);border:1px solid rgba(255,255,255,.24);border-radius:19px;box-shadow:0 20px 50px rgba(0,0,0,.26);backdrop-filter:blur(18px);font:12px/1.55 'DM Mono'}.system-card-head,.system-card-foot{display:flex;align-items:center;justify-content:space-between;color:#9db0c9;font-size:9px;text-transform:uppercase;letter-spacing:.1em}.system-card-head{padding-bottom:15px;border-bottom:1px solid rgba(255,255,255,.14)}.system-card-head .signal{width:6px;height:6px;margin-right:6px}.system-card-head span:last-child{margin-left:auto}.system-card code{display:block;padding:18px 0;color:#f3f6ff}.code-muted{color:#8296b0}.code-blue{color:#7cbbff}.code-string{color:#d6b8ff}.system-card-foot{padding-top:13px;border-top:1px solid rgba(255,255,255,.14)}.typing{color:#70dcff}.hero-bottom{position:absolute;z-index:2;bottom:31px;left:0;right:0;display:flex;justify-content:space-between;color:rgba(255,255,255,.7);font:11px 'DM Mono';text-transform:uppercase;letter-spacing:.08em}.scroll-cue{font-size:18px;animation:bob 1.7s infinite}.world{padding:125px 0 92px}.section-index{color:#597099;margin:0 0 26px}.world-grid{display:grid;grid-template-columns:1.08fr .75fr;gap:90px;align-items:end}.world h2{font-size:clamp(38px,4.3vw,61px);line-height:1;letter-spacing:-.065em;margin:0}.world-grid>p{font-size:16px;line-height:1.75;color:#3e4b60;margin:0}.service-row{border-top:1px solid var(--line);margin-top:80px;display:grid;grid-template-columns:repeat(3,1fr)}.service-row article{padding:23px 30px 20px 0;border-right:1px solid var(--line);min-height:178px}.service-row article+article{padding-left:30px}.service-row article:last-child{border-right:0}.service-row span{font:11px 'DM Mono';color:#5774a1}.service-row h3{font-size:20px;margin:30px 0 8px;letter-spacing:-.045em}.service-row p{margin:0;color:#627087;font-size:13px;line-height:1.55;max-width:255px}.footer{border-top:1px solid var(--line);padding:37px 0 110px;display:flex;justify-content:space-between;gap:30px;align-items:flex-start}.footer-kicker{font-weight:600;margin:0 0 9px}.footer p:not(.footer-kicker){margin:0;font-size:13px;color:#647087}.footer-links{display:flex;flex-direction:column;gap:9px;text-align:right}.footer-links a,.footer-links button{font:600 12px Manrope;color:var(--ink);border:0;background:none;padding:0;cursor:pointer;text-decoration:none}.quick-actions{position:fixed;z-index:20;bottom:34px;right:25px;display:flex;align-items:center;gap:9px}.quick-actions a,.assistant-launch{height:50px;border-radius:999px;text-decoration:none;display:flex;align-items:center;gap:9px;font:800 11px Manrope;letter-spacing:.02em;padding:0 16px;cursor:pointer}.whatsapp{background:#fff;color:#06142a;box-shadow:0 10px 30px rgba(0,0,0,.16)}.whatsapp span{color:#25c36a;font-size:20px}.assistant-launch{border:0;background:#1e60ff;color:#fff;box-shadow:0 10px 30px rgba(30,96,255,.35)}.assistant-launch span,.assistant-avatar{width:29px;height:29px;border-radius:50%;display:grid;place-items:center;background:#fff;color:#1e60ff;font:800 10px 'DM Mono'}.quick-actions i{font-style:normal}.chat-panel{position:fixed;z-index:31;right:24px;bottom:84px;width:min(405px,calc(100% - 32px));max-height:calc(100vh - 110px);overflow:auto;background:#f9f8f5;border:1px solid rgba(6,20,42,.14);border-radius:23px;box-shadow:0 25px 70px rgba(0,0,0,.3);padding:17px;transform:translateY(20px) scale(.97);opacity:0;pointer-events:none;transition:.28s ease}.chat-panel.is-open{opacity:1;pointer-events:auto;transform:none}.chat-backdrop{position:fixed;inset:0;background:rgba(2,9,20,.25);z-index:30;opacity:0;pointer-events:none;transition:.2s}.chat-backdrop.is-open{opacity:1;pointer-events:auto}.chat-panel-head{display:flex;gap:10px;align-items:center;padding-bottom:14px;border-bottom:1px solid var(--line)}.chat-panel-head p{font-size:13px;font-weight:800;margin:0}.chat-panel-head small{font:10px 'DM Mono';color:#708096}.chat-panel-head small span{width:6px;height:6px;background:#2bd77b;display:inline-block;border-radius:50%;margin-right:4px}.chat-panel-head>button,.privacy-dialog>button{margin-left:auto;width:31px;height:31px;border-radius:50%;border:1px solid var(--line);background:#fff;font-size:20px;line-height:1;cursor:pointer}.chat-intro{margin:16px 0;background:#e9efff;border-radius:14px;padding:13px}.chat-intro p{margin:0 0 8px;font-size:13px;line-height:1.5}.chat-intro a{font:700 11px 'DM Mono';color:#1248c8;text-decoration:none}.project-form{display:grid;gap:11px}.project-form label>span{display:block;font-size:11px;font-weight:800;margin-bottom:5px}.project-form input:not([type=checkbox]),.project-form textarea,.project-form select{width:100%;border:1px solid #d5dae2;border-radius:10px;background:#fff;padding:10px 11px;color:var(--ink);font:13px Manrope;outline:0}.project-form textarea{resize:vertical}.project-form input:focus,.project-form textarea:focus,.project-form select:focus{border-color:#2768ff;box-shadow:0 0 0 3px rgba(39,104,255,.11)}.form-pair{display:grid;grid-template-columns:1fr 1fr;gap:10px}.consent-check{display:flex;gap:8px;align-items:flex-start;font-size:10px;color:#5d6a7e;line-height:1.45}.consent-check input{margin-top:3px}.consent-check span{margin:0!important;font-weight:500!important}.submit-project{border:0;border-radius:11px;background:#082968;color:#fff;padding:13px;font:800 12px Manrope;cursor:pointer}.form-status{display:none;margin:0;font-size:12px}.honeypot{position:absolute;left:-9999px}.privacy-modal{position:fixed;z-index:40;inset:0;display:grid;place-items:center;padding:18px;background:rgba(4,15,32,.55);opacity:0;pointer-events:none;transition:.2s}.privacy-modal.is-open{opacity:1;pointer-events:auto}.privacy-dialog{width:min(590px,100%);background:#f9f8f5;border-radius:22px;padding:38px;position:relative}.privacy-dialog>button{position:absolute;right:17px;top:17px}.privacy-dialog h2{font-size:36px;letter-spacing:-.06em;max-width:420px;margin:0 0 18px}.privacy-dialog p:not(.section-index){font-size:14px;line-height:1.7;color:#526076}.cookie-bar{position:fixed;z-index:35;left:23px;bottom:23px;width:min(480px,calc(100% - 160px));padding:14px 15px;border-radius:16px;background:#fff;box-shadow:0 11px 35px rgba(0,0,0,.14);display:flex;gap:18px;align-items:center}.cookie-bar p{margin:0;font-size:10px;line-height:1.5;color:#4e5c70}.cookie-bar div{display:flex;gap:7px;white-space:nowrap}.cookie-bar button{border:0;background:none;color:#365071;font:700 10px Manrope;cursor:pointer}.cookie-bar #accept-cookies{background:#092969;color:#fff;border-radius:8px;padding:8px 10px}@keyframes cityBreathe{from{transform:scale(1.02)}to{transform:scale(1.075) translate(-.7%,-.5%)}}@keyframes pulse{50%{box-shadow:0 0 0 9px rgba(97,219,255,0)}}@keyframes bob{50%{transform:translateY(5px)}}@media(max-width:760px){.wrap{width:min(100% - 38px,1180px)}.topbar{height:70px}.topbar nav>a:first-child{display:none}nav{gap:13px}.hero{min-height:760px}.city-image{object-position:58% center}.city-vignette{background:linear-gradient(0deg,rgba(3,13,28,.68),rgba(3,13,28,.05) 68%),linear-gradient(90deg,rgba(3,13,28,.64),rgba(3,13,28,.05))}.hero-layout{min-height:710px;padding:130px 0 82px;align-items:flex-start;flex-direction:column;gap:35px}.hero h1{font-size:55px}.hero-lede{font-size:15px;line-height:1.6;margin:23px 0}.system-card{width:100%;margin:0;align-self:stretch}.hero-bottom{bottom:23px;font-size:9px}.world{padding:78px 0 62px}.world-grid{grid-template-columns:1fr;gap:24px}.world-grid>p{font-size:14px}.service-row{margin-top:48px;grid-template-columns:1fr}.service-row article,.service-row article+article{padding:21px 0;border-right:0;border-bottom:1px solid var(--line);min-height:auto}.service-row h3{margin:15px 0 7px}.footer{padding-bottom:125px;flex-direction:column}.footer-links{text-align:left}.quick-actions{right:14px;bottom:14px}.quick-actions i{display:none}.quick-actions a,.assistant-launch{width:50px;padding:0;justify-content:center}.assistant-launch{width:auto;padding:0 14px}.assistant-launch i{display:block}.chat-panel{right:16px;bottom:76px}.cookie-bar{left:14px;bottom:75px;width:calc(100% - 28px);gap:10px}.cookie-bar p{font-size:9px}.cookie-bar div{flex-direction:column}.form-pair{grid-template-columns:1fr}.privacy-dialog{padding:32px 24px}.privacy-dialog h2{font-size:30px}}

/* === motion.css === */
/* Autonomous day-to-night city cycle and a solid Portuguese tile wall. */
.city-image-day,.city-image-night{transition:opacity 8s cubic-bezier(.45,0,.2,1)}
.city-lights{position:absolute;inset:0;z-index:2;pointer-events:none}.city-lights i{position:absolute;width:5px;height:5px;border-radius:50%;background:#ffe5a2;box-shadow:0 0 13px 4px rgba(255,193,80,.76);opacity:0;transform:scale(.15);transition:opacity .6s ease,transform .6s ease}.city-lights i:nth-child(1){left:14%;top:51%;transition-delay:.3s}.city-lights i:nth-child(2){left:22%;top:39%;transition-delay:1s}.city-lights i:nth-child(3){left:29%;top:61%;transition-delay:1.7s}.city-lights i:nth-child(4){left:38%;top:48%;transition-delay:2.4s}.city-lights i:nth-child(5){left:46%;top:37%;transition-delay:3.1s}.city-lights i:nth-child(6){left:52%;top:59%;transition-delay:3.8s}.city-lights i:nth-child(7){left:58%;top:32%;transition-delay:4.5s}.city-lights i:nth-child(8){left:64%;top:55%;transition-delay:5.2s}.city-lights i:nth-child(9){left:70%;top:40%;transition-delay:5.9s}.city-lights i:nth-child(10){left:75%;top:62%;transition-delay:6.6s}.city-lights i:nth-child(11){left:81%;top:43%;transition-delay:7.3s}.city-lights i:nth-child(12){left:87%;top:58%;transition-delay:8s}body[data-city-mode="night"] .city-lights i{opacity:1;transform:scale(1)}.city-vignette{z-index:3;transition:background 8s ease}body[data-city-mode="night"] .city-vignette{background:linear-gradient(90deg,rgba(1,8,21,.9) 0%,rgba(1,8,21,.68) 30%,rgba(1,8,21,.16) 63%,rgba(1,8,21,.35) 100%),linear-gradient(0deg,rgba(1,8,21,.64),transparent 40%)}.hero-layout,.hero-bottom{z-index:4}
.world{width:100%;max-width:none;padding:120px max(36px,calc((100% - 1180px)/2)) 92px;color:#fff;background-image:url('azulejo-wall-bright.webp');background-size:560px;background-repeat:repeat;background-position:center}.world .section-index,.world-grid>p,.service-row p{color:rgba(255,255,255,.92)}.world-grid,.service-row{width:min(1180px,100%);margin-left:auto;margin-right:auto}.world .section-index{width:min(1180px,100%);margin-left:auto;margin-right:auto}.service-row{border-top-color:rgba(255,255,255,.5)}.service-row article{border-right-color:rgba(255,255,255,.4)}.service-row span{color:#c9e0ff}.world h2,.world h2 em,.service-row h3{color:#fff}@media(max-width:760px){.world{padding:78px 19px 62px;background-size:430px}.world-grid,.service-row,.world .section-index{width:100%}}

/* === capabilities.css === */
.capabilities{padding:122px 0 110px}.capabilities-head{display:grid;grid-template-columns:1.15fr .78fr;column-gap:92px;row-gap:18px;align-items:end}.capabilities-head .section-index{grid-column:1/-1;margin:0;color:#56729c}.capabilities h2{margin:0;font-size:clamp(39px,4.45vw,62px);line-height:1;letter-spacing:-.067em}.capabilities h2 em{font-family:'Playfair Display',serif;font-weight:600}.capabilities-head>p:last-child{margin:0 0 4px;color:#526076;font-size:15px;line-height:1.72}.capability-grid{margin-top:65px;border-top:1px solid var(--line);display:grid;grid-template-columns:repeat(2,1fr)}.capability-grid article{padding:29px 34px 30px 0;min-height:244px;border-bottom:1px solid var(--line)}.capability-grid article:nth-child(odd){border-right:1px solid var(--line);padding-right:34px}.capability-grid article:nth-child(even){padding-left:34px}.capability-no{font:11px 'DM Mono';color:#456dff}.capability-grid h3{font-size:22px;letter-spacing:-.05em;margin:35px 0 9px}.capability-grid p{font-size:13px;line-height:1.6;color:#59687d;max-width:410px;margin:0}.tech-tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:18px}.tech-tags b{font:500 10px 'DM Mono';color:#21487e;padding:6px 8px;border-radius:999px;background:#e6edfb}@media(max-width:760px){.capabilities{padding:78px 0 68px}.capabilities-head{display:block}.capabilities-head .section-index{margin-bottom:23px}.capabilities h2{font-size:41px}.capabilities-head>p:last-child{margin-top:21px;font-size:14px}.capability-grid{margin-top:45px;grid-template-columns:1fr}.capability-grid article,.capability-grid article:nth-child(odd),.capability-grid article:nth-child(even){min-height:0;padding:24px 0;border-right:0}.capability-grid h3{margin:16px 0 8px}}

/* === tile-experience.css === */
.world.tile-experience{position:relative;isolation:isolate;min-height:690px;padding:112px max(36px,calc((100% - 1180px)/2)) 100px;overflow:hidden;background:#e4dfd0 url('azulejo-wall-bright.webp') center/520px repeat;color:#081c3a}.world.tile-experience::before{content:"";position:absolute;inset:0;z-index:-1;background:radial-gradient(380px circle at var(--tile-x,50%) var(--tile-y,50%),rgba(255,255,255,.02) 0 16%,rgba(9,32,70,.12) 40%,rgba(5,21,49,.42) 100%);transition:background .12s linear}.world.tile-experience::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;background:linear-gradient(90deg,rgba(237,233,219,.12),transparent 35%,rgba(235,229,211,.08));mix-blend-mode:soft-light}.tile-copy{width:min(1180px,100%);margin:auto;position:relative;z-index:1}.tile-experience .section-index{margin:0 0 46px;color:#0f2e5a;font-weight:700;text-shadow:0 1px rgba(255,255,255,.35)}.tile-intro{display:grid;grid-template-columns:1.12fr .75fr;gap:120px;align-items:end}.tile-intro h2{color:#071f47;font-size:clamp(48px,5.4vw,74px);line-height:.95;margin:0;text-shadow:0 1px 0 rgba(255,255,255,.35)}.tile-intro h2 em{color:#0d417d}.tile-intro>p{margin:0 0 8px;color:#092757;font-size:16px;line-height:1.72;font-weight:600;max-width:450px}.tech-stream{display:flex;flex-wrap:wrap;gap:10px 11px;margin-top:85px;max-width:1040px}.tech-stream span{position:relative;display:inline-flex;align-items:center;height:43px;padding:0 16px;border-radius:999px;border:1px solid rgba(12,48,94,.48);background:rgba(255,255,255,.16);color:#082b5e;font:700 11px 'DM Mono';letter-spacing:.025em;box-shadow:inset 0 1px rgba(255,255,255,.45);transition:transform .22s ease,background .22s ease,color .22s ease}.tech-stream span:hover{transform:translateY(-6px) rotate(-1deg);background:#0a3b81;color:#fff;box-shadow:0 12px 25px rgba(7,31,71,.25)}.tile-note{margin:55px 0 0;color:#102e5b;font:600 10px 'DM Mono';letter-spacing:.09em;text-transform:uppercase}.tile-orbit{position:absolute;right:8%;bottom:9%;width:115px;height:115px;border:1px solid rgba(12,48,94,.5);border-radius:50%;pointer-events:none;animation:slowOrbit 8s linear infinite}.tile-orbit::before,.tile-orbit::after{content:"";position:absolute;width:10px;height:10px;border-radius:50%;background:#0c478f;box-shadow:0 0 0 7px rgba(255,255,255,.23)}.tile-orbit::before{top:-5px;left:50%}.tile-orbit::after{bottom:12px;right:0;background:#d9a843}@keyframes slowOrbit{to{transform:rotate(360deg)}}@media(max-width:760px){.world.tile-experience{min-height:640px;padding:78px 19px 70px;background-size:390px}.tile-experience .section-index{margin-bottom:32px}.tile-intro{display:block}.tile-intro h2{font-size:48px}.tile-intro>p{margin-top:26px;font-size:14px}.tech-stream{margin-top:52px;gap:8px}.tech-stream span{height:38px;padding:0 12px;font-size:10px}.tile-note{margin-top:34px;line-height:1.6;max-width:250px}.tile-orbit{width:75px;height:75px;right:10%;bottom:5%}}

/* === painted-hero.css === */
/* The hero animation is now only the painted city’s natural change of light. */
.city-lights{display:none!important}

/* === bright-tiles.css === */
/* A real, bright tile wall: no dimming layer, no transparency. */
.world.tile-experience{background:#fff url('azulejo-wall-bright.webp') center/768px repeat;color:#062c64}.world.tile-experience::before,.world.tile-experience::after{display:none}.tile-experience .section-index{color:#06336d;text-shadow:none}.tile-intro h2{color:#062e67;text-shadow:none}.tile-intro h2 em{color:#0752a2}.tile-intro>p{color:#06336d;text-shadow:0 1px 0 rgba(255,255,255,.85)}.tech-stream span{border-color:#0a4c9b;background:#fff;color:#06336d;box-shadow:0 2px 0 rgba(6,47,101,.12)}.tech-stream span:hover{background:#073f8c;color:#fff}.tile-note{color:#06336d}.tile-orbit{border-color:#0752a2}.tile-orbit::before{background:#0752a2}@media(max-width:760px){.world.tile-experience{background-size:530px}}

/* === tile-stickers.css === */
/* Content sits on the tile wall as tactile, colourful paper stickers. */
.tile-intro{align-items:center}.tile-experience .section-index{display:table;width:auto;padding:9px 13px!important;border:2px solid #092d67!important;border-radius:7px!important;background:#ffcc00!important;color:#082b63!important;box-shadow:4px 5px 0 #082b63!important;transform:rotate(-1.2deg);font-weight:800!important}.tile-intro h2{display:table;width:auto;max-width:700px;padding:22px 25px 25px!important;border:3px solid #082c65!important;border-radius:16px!important;background:#fffdf7!important;box-shadow:9px 10px 0 rgba(6,43,99,.9),inset 0 -7px 0 #7fc8ff!important;transform:rotate(-1.05deg);line-height:.93!important}.tile-intro h2 em{display:inline-block;transform:rotate(.7deg)}.tile-intro>p{padding:20px 21px!important;border:3px solid #082c65!important;border-radius:14px!important;background:#c73512!important;color:#fff!important;box-shadow:7px 8px 0 rgba(6,43,99,.9)!important;transform:rotate(1.25deg);font-weight:800!important;line-height:1.55!important}.tech-stream{gap:18px 16px!important;max-width:1100px!important}.tech-stream span{height:49px!important;padding:0 18px!important;border:2px solid #082c65!important;border-radius:11px!important;background:#fffdf9!important;color:#082c65!important;box-shadow:4px 5px 0 rgba(6,43,99,.85)!important;transform:rotate(-1.4deg);font-weight:700!important;transition:transform .2s cubic-bezier(.2,.9,.3,1.4),box-shadow .2s ease!important}.tech-stream span:nth-child(3n+1){background:#ffcc00!important}.tech-stream span:nth-child(3n+2){background:#00c2d1!important}.tech-stream span:nth-child(3n){background:#c73512!important;color:#fff!important}.tech-stream span:nth-child(5n){background:#7c4dff!important;color:#fff!important}.tech-stream span:nth-child(even){transform:rotate(1.1deg)}.tech-stream span:hover{transform:translateY(-10px) rotate(-2.5deg) scale(1.055)!important;background:#fffdf9!important;color:#082c65!important;box-shadow:7px 13px 0 rgba(6,43,99,.85)!important}.tile-note{display:table;width:auto;padding:8px 11px;border-radius:7px;background:#082d67!important;color:#fff!important;box-shadow:3px 4px 0 rgba(255,255,255,.78);transform:rotate(.8deg)}.tile-orbit{border-width:2px!important;background:#fff9!important;box-shadow:5px 6px 0 rgba(6,43,99,.85)}@media(max-width:760px){.tile-experience .section-index{font-size:9px}.tile-intro h2{padding:18px 17px 20px!important;border-radius:12px!important;box-shadow:6px 7px 0 rgba(6,43,99,.9),inset 0 -5px 0 #c5ddff!important}.tile-intro>p{margin-top:30px!important;padding:16px!important;box-shadow:5px 6px 0 rgba(6,43,99,.9)!important}.tech-stream{gap:13px 11px!important}.tech-stream span{height:43px!important;padding:0 13px!important;box-shadow:3px 4px 0 rgba(6,43,99,.85)!important}}

/* === galo-and-grid.css === */
/* A single Portuguese character replaces the decorative orb; skills form a balanced grid. */
.tech-stream{display:grid!important;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px!important;max-width:940px!important}.tech-stream span{justify-content:center;text-align:center;white-space:nowrap}.tile-orbit{display:none!important}@media(max-width:1050px){.tech-stream{max-width:100%!important}}@media(max-width:760px){.tech-stream{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px!important}.tech-stream span{width:100%;font-size:9px!important;padding:0 7px!important}}

/* === dusk-cycle.css === */
/* Eight hand-painted frames, paced as one gentle 18-second cinematic sunset. */
.city-image{opacity:0;will-change:opacity}.city-image-day{opacity:1}.city-visual{animation:cityTone 16s ease-in-out 10s infinite}.city-visual .city-image-day{animation:frameDay 16s ease-in-out 10s infinite}.city-visual .city-image-golden{animation:frameGolden 16s ease-in-out 10s infinite}.city-visual .city-image-dusk-off{animation:frameDuskOff 16s ease-in-out 10s infinite}.city-visual .city-image-lights-1{animation:frameLights1 16s ease-in-out 10s infinite}.city-visual .city-image-lights-2{animation:frameLights2 16s ease-in-out 10s infinite}.city-visual .city-image-dusk-on{animation:frameDuskOn 16s ease-in-out 10s infinite}.city-visual .city-image-blue{animation:frameBlue 16s ease-in-out 10s infinite}.city-visual .city-image-night{animation:frameNight 16s ease-in-out 10s infinite}.city-vignette{animation:vignetteTone 16s ease-in-out 10s infinite}
@keyframes frameDay{0%,6%{opacity:1}9%,85%{opacity:0}87.5%,100%{opacity:1}}@keyframes frameGolden{0%,6%{opacity:0}9%,11%{opacity:1}14%,100%{opacity:0}}@keyframes frameDuskOff{0%,9%{opacity:0}11%,14%{opacity:1}17%,100%{opacity:0}}@keyframes frameLights1{0%,11%{opacity:0}14%,17%{opacity:1}20%,100%{opacity:0}}@keyframes frameLights2{0%,14%{opacity:0}17%,20%{opacity:1}22%,100%{opacity:0}}@keyframes frameDuskOn{0%,17%{opacity:0}20%,22%{opacity:1}25%,100%{opacity:0}}@keyframes frameBlue{0%,20%{opacity:0}22%,25%{opacity:1}27%,100%{opacity:0}}@keyframes frameNight{0%,22%{opacity:0}25%,85%{opacity:1}87.5%,100%{opacity:0}}
@keyframes cityTone{0%,100%{filter:brightness(1) saturate(1);transform:scale(1.025)}33%{filter:brightness(.99) saturate(1.035);transform:scale(1.047) translateX(-.25%)}68%{filter:brightness(.95) saturate(1);transform:scale(1.062) translateX(.2%)}91%{filter:brightness(.91) saturate(.96);transform:scale(1.048)}}@keyframes vignetteTone{0%,9%{opacity:.78}19%,45%{opacity:.55}55%,69%{opacity:.66}79%,94%{opacity:1}100%{opacity:.78}}
@media(prefers-reduced-motion:reduce){.city-visual,.city-visual .city-image,.city-vignette{animation:none!important}.city-image-day{opacity:1}.city-image-golden,.city-image-dusk-off,.city-image-lights-1,.city-image-lights-2,.city-image-dusk-on,.city-image-blue,.city-image-night{opacity:0}}

/* === hero-animation-fix.css === */
/* Overrides the old two-frame rules. The eight-frame sequence is the only opacity owner. */
body .city-visual .city-image-day{animation:frameDay 16s ease-in-out 10s infinite!important}body .city-visual .city-image-golden{animation:frameGolden 16s ease-in-out 10s infinite!important}body .city-visual .city-image-dusk-off{animation:frameDuskOff 16s ease-in-out 10s infinite!important}body .city-visual .city-image-lights-1{animation:frameLights1 16s ease-in-out 10s infinite!important}body .city-visual .city-image-lights-2{animation:frameLights2 16s ease-in-out 10s infinite!important}body .city-visual .city-image-dusk-on{animation:frameDuskOn 16s ease-in-out 10s infinite!important}body .city-visual .city-image-blue{animation:frameBlue 16s ease-in-out 10s infinite!important}body .city-visual .city-image-night{animation:frameNight 16s ease-in-out 10s infinite!important}

/* === full-city-frame.css === */
/* Responsive art direction: preserve the tram and street without stretching the painting. */
.city-image{object-fit:cover!important;object-position:center 54%!important}
@media(min-width:1180px){.hero{min-height:clamp(700px,56.25vw,900px)}.city-image{object-position:center center!important}.hero-layout{min-height:clamp(650px,52vw,850px)}}
@media(min-width:761px) and (max-width:1179px){.hero{min-height:clamp(690px,68vw,820px)}.city-image{object-position:center 62%!important}.hero-layout{min-height:clamp(650px,64vw,780px)}}
@media(max-width:760px){.hero{min-height:780px}.city-image{object-position:58% 56%!important}.hero-layout{min-height:730px}.system-card{margin-top:auto}.hero-bottom{bottom:20px}}
@media(max-width:420px){.hero{min-height:735px}.city-image{object-position:57% 58%!important}.hero-layout{min-height:690px;padding-top:112px}.system-card{display:none}}

/* === footer-refresh.css === */
/* A compact closing scene instead of a flat grey footer. */
.footer {
  position: relative;
  max-width: none !important;
  width: 100% !important;
  min-height: 245px;
  margin: 0 !important;
  padding: 48px max(36px, calc((100% - 1180px) / 2)) 118px !important;
  display: grid !important;
  grid-template-columns: 1fr !important;
  align-content: center;
  gap: 34px;
  overflow: hidden;
  border: 0 !important;
  /* Layered instead of flat navy: ember wash top-left (echoes the CTA/grid-
     spotlight accent), a cool blue wash bottom-right (echoes .footer::before's
     ring), over a diagonal gradient that darkens toward #050f22 — close to
     .curtain-rise's own navy, so the footer bookends the entrance curtain
     instead of landing on an unrelated flat blue. */
  background:
    radial-gradient(1100px 560px at 12% -15%, rgba(240, 108, 40, 0.12), transparent 60%),
    radial-gradient(900px 520px at 102% 118%, rgba(129, 187, 255, 0.14), transparent 65%),
    linear-gradient(165deg, #050f22 0%, #0a2144 55%, #0c2c5c 100%) !important;
  color: #fff;
}
.footer-main {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  max-width: 420px;
}
/* A soft ambient wash behind the brand block, echoing the ember/blue glow
   used elsewhere on the page (grid-spotlight, atmosphere-glow) — without it
   the left content sat flat and isolated against the large empty middle of
   the section, which read as unfinished ("raw"). */
.footer-main::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: -60px;
  top: -50px;
  width: 320px;
  height: 320px;
  background: radial-gradient(circle, rgba(240, 108, 40, 0.14), transparent 70%);
  filter: blur(6px);
  pointer-events: none;
}
.footer::before {
  content: "";
  position: absolute;
  z-index: 0;
  right: -50px;
  bottom: -115px;
  width: 360px;
  height: 360px;
  border: 1px solid rgba(129, 187, 255, 0.32);
  border-radius: 50%;
  box-shadow:
    0 0 0 37px rgba(129, 187, 255, 0.05),
    0 0 0 74px rgba(129, 187, 255, 0.035);
}
.footer::after {
  content: "RE";
  position: absolute;
  z-index: 0;
  right: max(7%, calc((100% - 1180px) / 2));
  bottom: -36px;
  color: rgba(112, 174, 255, 0.09);
  font: 800 220px/0.8 Manrope;
  letter-spacing: -0.14em;
  pointer-events: none;
}
.footer > * {
  position: relative;
  z-index: 1;
}
.footer-kicker {
  display: flex !important;
  align-items: center;
  gap: 11px;
  margin: 0 0 11px !important;
  color: #9dcbff !important;
  font-size: 10px !important;
  letter-spacing: 0.17em !important;
}
.footer-kicker::before {
  content: "RE";
  display: grid;
  place-items: center;
  width: 29px;
  height: 29px;
  border-radius: 9px;
  background: #e8f2ff;
  color: #082a60;
  font: 800 10px "DM Mono";
}
.footer p:not(.footer-kicker) {
  max-width: 390px;
  color: #fff !important;
  font-size: 20px !important;
  line-height: 1.22 !important;
  letter-spacing: -0.035em;
}
.footer-links {
  display: flex !important;
  flex-wrap: wrap;
  align-items: center !important;
  justify-content: flex-start !important;
  gap: 12px !important;
  margin-top: 26px !important;
  padding-top: 22px !important;
  border-top: 1px solid rgba(157, 203, 255, 0.16);
  width: 100%;
}
.footer-links a,
.footer-links button {
  display: inline-flex !important;
  align-items: center;
  gap: 9px;
  padding: 12px 18px !important;
  border-radius: 999px !important;
  font-size: 11px !important;
  letter-spacing: 0.03em !important;
  white-space: nowrap;
  transition:
    border-color 0.2s ease,
    background 0.2s ease,
    color 0.2s ease,
    transform 0.2s ease;
}
.footer-links a {
  border: 1px solid rgba(181, 217, 255, 0.45) !important;
  background: rgba(255, 255, 255, 0.08) !important;
  color: #fff !important;
  font-weight: 700 !important;
  font-family: Manrope, sans-serif !important;
  box-shadow: inset 0 1px rgba(255, 255, 255, 0.16);
}
.footer-links a:hover {
  border-color: rgba(181, 217, 255, 0.75) !important;
  background: rgba(255, 255, 255, 0.13) !important;
  transform: translateY(-1px);
}
.footer-links a::after {
  content: "↗";
  font-size: 15px;
  color: #9dccff;
}
.footer-links button {
  border: 1px solid rgba(157, 203, 255, 0.3) !important;
  background: transparent !important;
  color: #c7d9f3 !important;
  font-weight: 700 !important;
  font-family: "DM Mono", monospace !important;
  letter-spacing: 0.1em !important;
  text-transform: uppercase;
}
.footer-links button::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #9dcbff;
  box-shadow: 0 0 7px rgba(157, 203, 255, 0.85);
}
.footer-links button:hover {
  border-color: rgba(157, 203, 255, 0.6) !important;
  background: rgba(157, 203, 255, 0.08) !important;
  color: #fff !important;
  text-decoration: none;
  transform: translateY(-1px);
}
@media (max-width: 760px) {
  .footer {
    min-height: 270px;
    padding: 42px 19px 124px !important;
    grid-template-columns: 1fr !important;
    gap: 23px;
  }
  .footer::after {
    right: -15px;
    bottom: -25px;
    font-size: 155px;
  }
  .footer::before {
    right: -100px;
    bottom: -135px;
  }
  .footer-main::before {
    left: -30px;
    top: -30px;
    width: 240px;
    height: 240px;
  }
  .footer p:not(.footer-kicker) {
    font-size: 18px !important;
  }
  .footer-links {
    align-items: flex-start !important;
    justify-content: flex-start;
  }
  .footer-links a,
  .footer-links button {
    font-size: 11px !important;
  }
}

/* === bespoke-refinement.css === */
/* Editorial proof of the bespoke positioning — quiet, not salesy. */
.bespoke-line{display:flex;align-items:flex-start;gap:8px;max-width:470px;margin:0 0 24px;padding:9px 12px;border:1px solid rgba(255,255,255,.35);border-radius:13px;background:rgba(5,20,45,.28);color:rgba(255,255,255,.92);font:600 10px/1.55 'DM Mono';letter-spacing:.02em;backdrop-filter:blur(9px)}.bespoke-line::before{content:"✦";color:#f4c952;font-size:13px}.made-to-measure{max-width:570px;margin:43px 0 0;padding:15px 18px;border-left:4px solid #d72f42;color:#082d63!important;background:#fffdf5;font-size:14px!important;font-weight:800;line-height:1.55!important;box-shadow:5px 6px 0 rgba(6,43,99,.78);transform:rotate(-.35deg)}@media(max-width:760px){.bespoke-line{margin-bottom:19px;font-size:9px}.made-to-measure{margin-top:34px;font-size:12px!important}}

/* === contact-refinement.css === */
/* Contact surface: an intentional assistant, not a generic floating form. */
.quick-actions { gap:10px; bottom:max(24px, env(safe-area-inset-bottom)); align-items:flex-end; }
.assistant-launch { position:relative; isolation:isolate; width:164px; min-height:172px; padding:0; border:0; background:transparent; box-shadow:none; color:transparent; overflow:visible; }
.assistant-launch:hover { transform:translateY(-4px); box-shadow:none; }
.assistant-launch>span { display:none; }
.assistant-launch i { display:none; }
.assistant-launch::before { content:''; position:absolute; z-index:0; left:50%; bottom:14px; width:110px; height:110px; transform:translateX(-50%); border-radius:50%; background:radial-gradient(circle,rgba(97,219,255,.32),rgba(16,52,90,.14) 60%,transparent 75%); animation:assistant-robot 4.8s ease-in-out infinite; }
.robot-img { position:absolute; z-index:1; pointer-events:none; }
.assistant-launch .robot-img { left:50%; bottom:-4px; height:150px; width:auto; transform:translateX(-50%); filter:drop-shadow(0 15px 13px rgba(18,25,35,.3)); animation:assistant-robot 4.8s ease-in-out infinite; }
.assistant-launch::after { content:'Assistente ReWebFolio'; position:absolute; z-index:2; left:50%; bottom:151px; transform:translateX(-50%) rotate(-2deg); width:max-content; padding:8px 11px; border:1px solid rgba(89,35,9,.42); border-radius:999px; background:linear-gradient(135deg,#ffb15b,#f06c28); color:#142842; box-shadow:0 8px 20px rgba(18,25,35,.28),inset 0 1px rgba(255,255,255,.34); font:800 10px Manrope,Arial,sans-serif; letter-spacing:.01em; white-space:nowrap; }
.assistant-avatar { position:relative; display:grid; place-items:center; flex:0 0 auto; overflow:visible; background:#fff; }
.chat-panel { width:min(430px,calc(100% - 28px)); right:18px; bottom:88px; padding:20px; border:1px solid rgba(21,87,238,.15); border-radius:28px; box-shadow:0 28px 80px rgba(3,17,42,.38); scrollbar-color:#b7c9ee transparent; }
.chat-panel-head { gap:12px; padding:0 0 16px; }
.chat-panel-head p { font-size:14px; letter-spacing:-.02em; }
.chat-panel-head small { display:flex; align-items:center; gap:5px; margin-top:3px; }
.chat-panel-head small span:first-child { display:none; }
.assistant-avatar { width:48px; height:48px; border:2px solid #fff; border-radius:17px; background:#102842; color:transparent; font-size:0; box-shadow:0 8px 20px rgba(18,25,35,.22); }
.assistant-avatar::before { content:''; position:absolute; left:14px; top:19px; width:5px; height:5px; border-radius:50%; background:#8ef1ff; box-shadow:11px 0 0 #8ef1ff,0 0 5px 1px rgba(142,241,255,.75),11px 0 5px 1px rgba(142,241,255,.75); }
.assistant-avatar::after { content:''; position:absolute; z-index:2; right:-2px; bottom:-2px; width:11px; height:11px; border:2px solid #f9f8f5; border-radius:50%; background:#2bc779; box-shadow:0 2px 5px rgba(2,31,17,.25); }
.chat-panel.is-open .assistant-avatar { animation:assistant-greeting .72s cubic-bezier(.18,.86,.35,1.35) both; }
.chat-panel.is-open .chat-intro { animation:chat-reveal .42s .08s both; }
.chat-panel.is-open .lead-progress { animation:chat-reveal .42s .14s both; }
.chat-panel-head>button { width:36px; height:36px; border-color:#dbe3f0; color:#172b4d; }
.chat-panel-head small span:last-child { width:auto; height:auto; margin:0; padding:0; background:transparent; color:#708096; white-space:nowrap; }
.assistant-stage { position:relative; min-height:150px; margin:12px 0 18px; overflow:hidden; border:1px solid rgba(185,137,49,.28); border-radius:22px; background:radial-gradient(circle at 82% 22%,rgba(188,142,56,.28),transparent 28%),linear-gradient(135deg,#0b1e34,#172b44); box-shadow:inset 0 1px rgba(255,255,255,.08),0 12px 28px rgba(8,23,42,.14); }
.assistant-stage::before { content:''; position:absolute; inset:auto -32px -48px auto; width:178px; height:178px; border:1px solid rgba(211,164,75,.24); border-radius:50%; }
.assistant-stage::after { content:''; position:absolute; top:20px; right:24px; width:5px; height:5px; border-radius:50%; background:#ffbf45; box-shadow:16px 18px #ffbf45,-14px 46px rgba(255,191,69,.65); animation:stage-sparks 3.2s ease-in-out infinite; }
.assistant-message { position:relative; z-index:2; width:61%; padding:18px; }
.assistant-message p { margin:0; color:#f6f2e9; font:600 12px/1.48 Manrope,Arial,sans-serif; }
.assistant-message .chat-typing { margin-top:9px; }
.assistant-message .chat-typing i { background:#ffbf45; }
.assistant-scene { position:absolute; z-index:1; right:-13px; bottom:-28px; width:174px; height:174px; filter:drop-shadow(0 18px 16px rgba(0,0,0,.38)); animation:stage-robot 4.8s ease-in-out infinite; }
.assistant-scene::before { content:''; position:absolute; z-index:0; left:50%; bottom:10%; width:66%; height:66%; transform:translateX(-50%); border-radius:50%; background:radial-gradient(circle,rgba(97,219,255,.3),rgba(16,52,90,.12) 60%,transparent 75%); }
.assistant-scene .robot-img { right:0; bottom:0; height:100%; width:auto; }
.chat-panel.is-open .assistant-stage { animation:stage-reveal .48s .06s cubic-bezier(.2,.8,.3,1) both; }
.chat-panel.is-open .assistant-scene { animation:stage-robot 4.8s .35s ease-in-out infinite,stage-arrive .65s .1s cubic-bezier(.17,.88,.34,1.22) both; }
.chat-intro { position:relative; overflow:hidden; margin:14px 0 16px; padding:14px 15px; border:1px solid #cce5d2; border-radius:17px; background:#f0f8f1; }
.chat-intro p { margin:0; color:#244634; font-size:12px; line-height:1.5; }
.project-form { gap:12px; }
.form-kicker { margin:1px 0 0; color:#9a6b24; font:800 10px/1 Manrope,Arial,sans-serif; letter-spacing:.1em; text-transform:uppercase; }
.project-form input::placeholder,.project-form textarea::placeholder { color:#8996aa; }
.project-form label>span { margin-bottom:6px; color:#1a2b47; font-size:10px; letter-spacing:.01em; }
.project-form input:not([type=checkbox]),.project-form textarea,.project-form select { min-height:43px; border-color:#d4deed; border-radius:13px; padding:10px 12px; font-size:12px; }
.project-form textarea { min-height:72px; }
.form-pair { gap:12px; }
.consent-check { padding:9px 10px; border-radius:12px; background:#f0f4fa; }
.submit-project { min-height:48px; border-radius:999px; background:linear-gradient(105deg,#102b4a,#1d4269); box-shadow:0 10px 22px rgba(11,31,54,.26); transition:transform .18s ease,box-shadow .18s ease; }
.submit-project:hover { transform:translateY(-1px); box-shadow:0 14px 26px rgba(11,31,54,.32); }
.submit-project:disabled { opacity:.62; cursor:wait; }
.form-status { padding:0 3px; }
.lead-success { display:grid; gap:12px; padding:26px 18px 18px; border:1px solid rgba(185,137,49,.3); border-radius:22px; background:linear-gradient(145deg,#f8f3e8,#fff); text-align:center; animation:lead-step-in .42s cubic-bezier(.2,.75,.3,1); }
.lead-success[hidden] { display:none; }
.lead-success-mark { display:grid; width:46px; height:46px; margin:0 auto 3px; place-items:center; border-radius:50%; background:#102b4a; color:#ffce6d; font:800 22px/1 Manrope,Arial,sans-serif; box-shadow:0 10px 22px rgba(11,31,54,.2); }
.lead-success h3 { margin:0; color:#102842; font:800 27px/1 Manrope,Arial,sans-serif; letter-spacing:-.06em; }
.lead-success>p:not(.form-kicker) { max-width:330px; margin:0 auto; color:#586a81; font-size:12px; line-height:1.55; }
.lead-success .wizard-back { min-height:43px; margin-top:4px; }
.lead-wizard { display:block; }
.lead-progress { display:grid; grid-template-columns:repeat(3,1fr); gap:6px; margin:0 0 16px; }
.lead-progress span { height:4px; border-radius:999px; background:#dce7df; transition:background .35s ease,transform .35s ease; }
.lead-progress span.is-active { background:linear-gradient(90deg,#172b44,#c19445); transform:scaleY(1.2); }
.lead-step { animation:lead-step-in .38s cubic-bezier(.2,.75,.3,1); }
.lead-step.is-active { display:grid; gap:12px; }
.lead-step[hidden] { display:none; }
.lead-step h3 { margin:8px 0 5px; color:#102842; font:750 clamp(20px,5vw,24px)/1.08 Manrope,Arial,sans-serif; letter-spacing:-.05em; }
.step-copy { margin:0 0 16px; color:#64738a; font-size:12px; line-height:1.5; }
.wizard-next,.wizard-back { min-height:46px; border-radius:999px; font:800 12px Manrope,Arial,sans-serif; transition:transform .2s ease,box-shadow .2s ease,background .2s ease; }
.wizard-next { width:100%; margin-top:4px; border:1px solid #102b4a; background:linear-gradient(105deg,#102b4a,#1d4269); color:#fff; box-shadow:0 10px 22px rgba(11,31,54,.22); }
.wizard-next:hover,.wizard-back:hover { transform:translateY(-2px); }
.wizard-actions { display:grid; grid-template-columns:.72fr 1.28fr; gap:10px; align-items:center; margin-top:4px; }
.wizard-actions .submit-project { margin:0; }
.wizard-back { border:1px solid #d4deed; background:#fff; color:#31445f; }
.choice-group { min-inline-size:0; margin:0; padding:0; border:0; }
.choice-group legend { margin:0 0 8px; padding:0; color:#1a2b47; font:800 10px/1.3 Manrope,Arial,sans-serif; letter-spacing:.01em; }
.choice-grid { display:grid; gap:8px; }
.contact-choice { grid-template-columns:repeat(3,1fr); }
.choice-grid label { position:relative; display:block; min-width:0; margin:0; }
.choice-grid input { position:absolute; opacity:0; pointer-events:none; }
.choice-grid label>span { display:flex; align-items:center; justify-content:center; min-height:43px; padding:9px 7px; border:1px solid #d7e1ee; border-radius:14px; background:#fff; color:#53647b; font:700 11px Manrope,Arial,sans-serif; cursor:pointer; transition:border-color .18s ease,background .18s ease,color .18s ease,transform .18s ease,box-shadow .18s ease; }
.choice-grid label>span b { margin-left:5px; font-weight:800; }
.choice-grid input:checked+span { border-color:#172b44; background:#172b44; color:#fff; box-shadow:0 8px 18px rgba(18,43,68,.2); transform:translateY(-1px); }
.choice-grid input:focus-visible+span { outline:3px solid rgba(185,148,69,.35); outline-offset:2px; }
.project-choice { grid-template-columns:repeat(2,1fr); }
.project-choice label>span { display:grid; justify-content:start; min-height:84px; padding:12px; text-align:left; }
.project-choice label>span i { display:block; margin:0 0 7px; color:#b27b26; font:800 9px/1 Manrope,Arial,sans-serif; font-style:normal; letter-spacing:.1em; }
.project-choice label>span b { margin:0; color:#152b47; font-size:12px; }
.project-choice label>span small { display:block; margin-top:3px; color:#77869b; font:500 9px/1.35 Manrope,Arial,sans-serif; }
.project-choice input:checked+span b,.project-choice input:checked+span small,.project-choice input:checked+span i { color:inherit; }
.chat-typing { display:flex; gap:4px; margin-top:10px; }
.chat-typing i { display:block; width:5px; height:5px; border-radius:50%; background:#176b3a; animation:chat-dot 1.1s ease-in-out infinite; }
.chat-typing i:nth-child(2) { animation-delay:.14s; }
.chat-typing i:nth-child(3) { animation-delay:.28s; }
@keyframes lead-step-in { from { opacity:0; transform:translate3d(12px,8px,0); } to { opacity:1; transform:translate3d(0,0,0); } }
@keyframes chat-dot { 0%,80%,100% { transform:translateY(0); opacity:.35; } 40% { transform:translateY(-4px); opacity:1; } }
@keyframes stage-reveal { from { opacity:0; transform:translateY(12px) scale(.97); } to { opacity:1; transform:translateY(0) scale(1); } }
@keyframes stage-arrive { from { opacity:0; transform:translate3d(42px,26px,0) rotate(8deg); } to { opacity:1; transform:translate3d(0,0,0) rotate(0); } }
@keyframes stage-robot { 0%,100% { transform:translate3d(0,0,0) rotate(-1.5deg); } 50% { transform:translate3d(-3px,-8px,0) rotate(1.5deg); } }
@keyframes stage-sparks { 0%,100% { opacity:.35; transform:translateY(0); } 50% { opacity:1; transform:translateY(-6px); } }
@keyframes assistant-greeting { 0% { transform:scale(.72) rotate(-12deg); } 65% { transform:scale(1.08) rotate(4deg); } 100% { transform:scale(1) rotate(0); } }
@keyframes chat-reveal { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:translateY(0); } }
@media(max-width:760px){.quick-actions{right:10px;bottom:max(8px,env(safe-area-inset-bottom));gap:4px}.quick-actions a{width:54px;padding:0;justify-content:center;margin-bottom:0}.quick-actions a i{display:none}.assistant-launch{width:142px;min-height:153px;padding:0}.assistant-launch::before{width:158px;height:158px;bottom:-12px}.assistant-launch::after{bottom:136px;padding:7px 9px;font-size:9px}.chat-panel{top:max(12px,env(safe-area-inset-top));right:12px;bottom:76px;width:calc(100% - 24px);max-height:none;padding:17px;border-radius:24px}.assistant-stage{min-height:136px;margin:10px 0 15px}.assistant-message{width:62%;padding:15px}.assistant-message p{font-size:11px}.assistant-scene{right:-9px;bottom:-30px;width:158px;height:158px}.project-form{gap:10px}.project-form textarea{min-height:62px}.project-form input:not([type=checkbox]),.project-form textarea,.project-form select{min-height:40px}.form-pair{gap:9px}}
@media(max-width:390px){.assistant-launch{width:134px;min-height:145px}.assistant-launch::before{width:150px;height:150px}.assistant-launch::after{bottom:128px}.form-pair{grid-template-columns:1fr}}

@keyframes assistant-robot { 0%,100% { transform:translateX(-50%) translate3d(0,0,0) rotate(-2deg); } 50% { transform:translateX(-50%) translate3d(0,-8px,0) rotate(2deg); } }
@media(prefers-reduced-motion:reduce){.assistant-launch::before,.robot-img,.assistant-scene,.assistant-stage,.chat-typing i,.assistant-avatar,.chat-intro,.lead-progress{animation:none!important}.lead-step{animation:none}}

/* Assistant widget: compact, viewport-safe launcher and usable dialog. */
.quick-actions{z-index:50;right:clamp(12px,2vw,28px);bottom:max(16px,env(safe-area-inset-bottom));pointer-events:none}
.quick-actions>*{pointer-events:auto}
.assistant-launch{width:136px;min-height:138px;border-radius:24px;outline-offset:5px;transition:transform .2s ease}
.assistant-launch::before{bottom:2px;width:104px;height:104px;opacity:.78}
.assistant-launch .robot-img{bottom:0;width:126px;height:144px;object-fit:contain;object-position:center bottom;filter:drop-shadow(0 12px 12px rgba(7,22,43,.32))}
.assistant-launch::after{content:'Assistente';bottom:126px;padding:7px 11px;border-color:rgba(33,91,158,.35);background:#0c2848;color:#fff;box-shadow:0 8px 22px rgba(4,18,37,.3);font-size:10px;transform:translateX(-50%)}
.assistant-launch:focus-visible{outline:3px solid #65dfff}
.chat-panel{z-index:61;right:clamp(12px,2vw,28px);bottom:24px;max-height:min(760px,calc(100dvh - 48px));overscroll-behavior:contain;scrollbar-gutter:stable;transform-origin:bottom right}
.chat-backdrop{z-index:60;background:rgba(2,9,20,.34);backdrop-filter:blur(2px)}
.chat-panel-head{position:sticky;z-index:5;top:-20px;margin:-20px -20px 0;padding:16px 20px;background:rgba(249,248,245,.96);backdrop-filter:blur(12px)}
.chat-panel-head>button:focus-visible,.project-form :focus-visible{outline:3px solid rgba(36,108,255,.3);outline-offset:2px}
body:has(.chat-panel.is-open) .quick-actions{opacity:0;pointer-events:none}
@media(max-width:760px){
  body:has(.cookie-bar:not([hidden])) .quick-actions{opacity:0;visibility:hidden;pointer-events:none}
  .quick-actions{right:8px;bottom:max(8px,env(safe-area-inset-bottom))}
  .assistant-launch{width:104px;min-height:112px}
  .assistant-launch .robot-img{width:100px;height:114px}
  .assistant-launch::before{width:88px;height:88px;bottom:0}
  .assistant-launch::after{bottom:101px;padding:6px 9px;font-size:9px}
  .chat-panel{inset:max(8px,env(safe-area-inset-top)) 8px max(8px,env(safe-area-inset-bottom));width:auto;max-height:none;border-radius:22px;padding:16px}
  .chat-panel-head{top:-16px;margin:-16px -16px 0;padding:14px 16px}
  .assistant-stage{min-height:128px}
  .assistant-message{width:64%;padding:14px}
  .assistant-scene{width:146px;height:146px}
}

/* Crisp code-native country and footer icons (no emoji-font dependency). */
.lang-switch .flag-icon{position:relative;display:inline-block;flex:0 0 auto;width:18px;height:12px;border-radius:2px;overflow:hidden;border:1px solid rgba(255,255,255,.58);box-shadow:0 1px 3px rgba(2,15,35,.28);transform:none;filter:none}
.flag-pt{background:linear-gradient(90deg,#066b3a 0 40%,#db2535 40%)}
.flag-pt::after{content:"";position:absolute;left:6px;top:3px;width:4px;height:4px;border:1px solid #ffd34e;border-radius:50%}
.flag-es{background:linear-gradient(#aa151b 0 25%,#f1bf00 25% 75%,#aa151b 75%)}
.flag-gb{background:linear-gradient(32deg,transparent 43%,#fff 43% 50%,#c8102e 50% 56%,#fff 56% 63%,transparent 63%),linear-gradient(-32deg,transparent 43%,#fff 43% 50%,#c8102e 50% 56%,#fff 56% 63%,transparent 63%),linear-gradient(90deg,transparent 40%,#fff 40% 45%,#c8102e 45% 55%,#fff 55% 60%,transparent 60%),linear-gradient(transparent 34%,#fff 34% 40%,#c8102e 40% 60%,#fff 60% 66%,transparent 66%),#012169}
.flag-br{background:#149447}
.flag-br::before{content:"";position:absolute;left:4px;top:2px;width:8px;height:8px;background:#ffdf00;transform:rotate(45deg)}
.flag-br::after{content:"";position:absolute;left:7px;top:4px;width:5px;height:5px;border-radius:50%;background:#002776}
.footer-links .footer-email,.footer-links button[data-open-privacy]{display:inline-flex;align-items:center;gap:9px}
.footer-links .footer-email::before,.footer-links button[data-open-privacy]::before{content:"";width:18px;height:18px;flex:0 0 auto;background:center/contain no-repeat}
.footer-links .footer-email::before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238fdcff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='14' rx='4'/%3E%3Cpath d='m5 8 7 5 7-5'/%3E%3C/svg%3E")}
.footer-links button[data-open-privacy]::before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238fdcff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='5' y='10' width='14' height='10' rx='3'/%3E%3Cpath d='M8 10V7a4 4 0 0 1 8 0v3M12 14v2'/%3E%3C/svg%3E")}
.footer-social span{width:24px;height:24px;border-radius:8px}
.footer-social span svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.footer-social span svg .icon-fill{fill:currentColor;stroke:none}
@media(max-width:760px){.lang-switch .flag-icon{width:16px;height:11px}.lang-switch a{gap:4px!important}.footer-social span{width:22px;height:22px}}
@media(max-width:380px){.assistant-launch{width:94px;min-height:104px}.assistant-launch .robot-img{width:92px;height:106px}.assistant-launch::after{bottom:94px}.contact-choice{grid-template-columns:1fr}.project-choice{grid-template-columns:1fr}}

/* === portfolio-work.css === */
.selected-work {
  position: relative;
  z-index: 0;
  isolation: isolate;
  padding: 112px 0 126px;
  overflow: hidden;
  background: #071321;
}

/* A quiet, contemporary nod to Lisbon's calçada — distinct from the azulejo wall above. */
.selected-work::before {
  position: absolute;
  z-index: 0;
  top: 0;
  bottom: auto;
  left: 50%;
  width: 100vw;
  height: 540px;
  transform: translateX(-50%);
  content: "";
  background-color: #071321;
  background-image:
    linear-gradient(180deg, rgba(2, 10, 18, 0.03) 0%, rgba(2, 10, 18, 0.05) 58%, #071321 100%),
    url("assets/projects/museum-gallery-rig.webp?v=1");
  /* Keep the material close to its native resolution instead of stretching it
     vertically across the whole projects gallery. */
  /* The image is deliberately bound to the viewport, not stretched through
     the whole gallery height. This keeps the fresco at native visual detail. */
  background-position: center, center top;
  background-size: cover, cover;
  background-repeat: no-repeat;
  background-attachment: scroll, scroll;
}

.selected-work::after {
  position: absolute;
  z-index: 0;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background:
    radial-gradient(ellipse at 20% 38%, rgba(255, 214, 135, 0.07), transparent 15%),
    radial-gradient(ellipse at 50% 38%, rgba(255, 214, 135, 0.07), transparent 15%),
    radial-gradient(ellipse at 80% 38%, rgba(255, 214, 135, 0.07), transparent 15%),
    linear-gradient(90deg, rgba(1, 8, 15, 0.16), transparent 42%, rgba(1, 8, 15, 0.14));
  content: "";
}

.selected-work > * {
  position: relative;
  z-index: 1;
}

.selected-work::before {
  animation: museum-wall-breathe 16s ease-in-out infinite alternate;
}

.selected-work::after {
  animation: museum-light-pass 13s ease-in-out infinite;
}

.selected-work-inner {
  position: relative;
}

.selected-work-inner::before {
  position: absolute;
  z-index: 0;
  top: 82px;
  right: -7vw;
  width: min(38vw, 520px);
  height: min(38vw, 520px);
  border: 1px solid rgba(237, 190, 102, 0.18);
  border-radius: 50%;
  box-shadow:
    0 0 0 42px rgba(237, 190, 102, 0.025),
    0 0 0 84px rgba(237, 190, 102, 0.018),
    0 0 110px rgba(232, 169, 62, 0.13);
  content: "";
  opacity: 0.55;
  pointer-events: none;
  transform: translate3d(calc(var(--museum-x, 0px) * 0.08), calc(var(--museum-y, 0px) * 0.06), 0);
  transition: transform 1.1s cubic-bezier(0.2, 0.7, 0.2, 1);
}

.selected-work-inner > * {
  position: relative;
  z-index: 1;
}
.work-heading {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(260px, 0.55fr);
  gap: clamp(24px, 6vw, 94px);
  align-items: end;
  margin-bottom: 52px;
}
.work-heading .section-index {
  grid-column: 1;
  width: max-content;
  margin: 0;
  padding: 0 0 15px;
  border: 0;
  border-bottom: 1px solid rgba(255, 229, 186, 0.42);
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: #f6d8ad;
  letter-spacing: 0.16em;
  text-align: left;
  writing-mode: initial;
  transform: none;
}
.work-heading > div {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(260px, 0.55fr);
  align-items: end;
  column-gap: clamp(24px, 6vw, 94px);
}
.work-heading h2 {
  grid-column: 1;
  max-width: none;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: #fff7e9;
  font:
    800 clamp(44px, 5.2vw, 75px) / 0.92 Manrope,
    Arial,
    sans-serif;
  letter-spacing: -0.07em;
  transform: none;
}
.work-heading h2 em {
  color: #ffb36f;
  font-family: "Playfair Display", serif;
  font-weight: 600;
}
.work-heading p:last-child {
  grid-column: 2;
  justify-self: end;
  max-width: 340px;
  margin: 0 0 5px;
  padding: 3px 0 3px 22px;
  border: 0;
  border-left: 2px solid #f6d8ad;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: #fff5e4;
  font-size: 14px;
  line-height: 1.7;
  transform: none;
}
.work-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}
.work-card {
  position: relative;
  display: flex;
  min-height: 340px;
  flex-direction: column;
  overflow: hidden;
  padding: 24px;
  border: 1px solid rgba(10, 38, 71, 0.12);
  border-radius: 26px;
  background: #fffdf8;
  box-shadow: 0 12px 30px rgba(6, 30, 60, 0.08);
  color: #102842;
  isolation: isolate;
  transition:
    transform 0.3s ease,
    box-shadow 0.3s ease;
}
.work-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 20px 42px rgba(6, 30, 60, 0.15);
}
.work-card::after {
  position: absolute;
  z-index: -1;
  right: -45px;
  bottom: -62px;
  width: 180px;
  height: 180px;
  border: 1px solid currentColor;
  border-radius: 50%;
  content: "";
  opacity: 0.16;
}
.work-card-top {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  color: #52718f;
  font:
    700 10px Manrope,
    Arial,
    sans-serif;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}
.work-card h3 {
  margin: auto 0 9px;
  font:
    800 clamp(29px, 4vw, 44px) / 0.92 Manrope,
    Arial,
    sans-serif;
  letter-spacing: -0.07em;
}
.work-card p {
  max-width: 420px;
  margin: 0;
  color: #50627b;
  font-size: 13px;
  line-height: 1.55;
}
.work-card ul {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 20px 0;
  padding: 0;
  list-style: none;
}
.work-card li {
  padding: 6px 8px;
  border-radius: 999px;
  background: rgba(16, 40, 66, 0.07);
  color: #38516e;
  font:
    700 9px Manrope,
    Arial,
    sans-serif;
}
.work-card a,
.work-card-note {
  display: inline-flex;
  align-items: center;
  width: max-content;
  margin-top: auto;
  color: #102842;
  font:
    800 11px Manrope,
    Arial,
    sans-serif;
  text-decoration: none;
}
.work-card a {
  border-bottom: 1px solid currentColor;
  padding-bottom: 3px;
}
.work-card--re {
  background: linear-gradient(145deg, #eff5ff, #fffdf8 64%);
  color: #143a7a;
}
.work-card--saloonix {
  background: linear-gradient(145deg, #fff9ec, #fffdf8 62%);
  color: #7d5317;
}
.work-card--cafe {
  background: linear-gradient(145deg, #f6f0e8, #fffdf8 66%);
  color: #70452b;
}
.work-card--evoline {
  background: linear-gradient(145deg, #eef7f7, #fffdf8 66%);
  color: #1d6269;
}

/* Public, live work replaces placeholder portfolio cards. */
.work-grid--legacy {
  display: none;
}

.work-grid--featured {
  grid-template-columns: repeat(6, minmax(0, 1fr));
  align-items: stretch;
}

.work-card--featured {
  grid-column: span 2;
  min-height: 735px;
  padding: 28px 30px 30px;
  border: 7px solid #b88a3a;
  border-radius: 13px;
  background:
    linear-gradient(180deg, rgba(255, 215, 145, 0.2), transparent 26%),
    #fffdf8;
  box-shadow:
    0 0 0 2px #10243b,
    0 0 0 4px rgba(239, 203, 128, 0.86),
    0 18px 36px rgba(0, 0, 0, 0.3),
    inset 0 0 0 1px rgba(255, 255, 255, 0.65);
  transform: perspective(1200px) translate3d(0, 0, 0) rotate(var(--gallery-tilt, 0deg));
  transform-style: preserve-3d;
  transition:
    opacity 0.7s ease,
    transform 0.55s cubic-bezier(0.2, 0.8, 0.2, 1),
    box-shadow 0.4s ease;
}

.work-card--featured::before {
  position: absolute;
  z-index: 0;
  top: -4px;
  left: 18%;
  width: 64%;
  height: 150px;
  border-radius: 50%;
  background: radial-gradient(ellipse at center top, rgba(255, 205, 111, 0.42), rgba(255, 205, 111, 0.08) 44%, transparent 70%);
  content: "";
  filter: blur(8px);
  opacity: 0.75;
  pointer-events: none;
  transform: translateY(-10px);
  animation: exhibit-light 7.5s ease-in-out infinite alternate;
}

.work-card--gisele-home {
  --screen-scale: 1.16;
  color: #482f3d;
  background: #fffafb;
}

.work-card--gisele-training {
  --screen-scale: 1.16;
  color: #6c4c41;
  background: #fffaf6;
}

.work-card--evoline-live {
  color: #1a5266;
  background: #f3f8f8;
}

.work-card--saloonix-live {
  color: #183d80;
  background: #f5f8ff;
}

.work-card--cafeconart-live {
  --screen-scale: 1.34;
  color: #6d371f;
  background: #fff7ed;
}

/* One neutral exhibition surface lets the live mobile work carry the colour. */
.work-card--featured,
.work-card--gisele-home,
.work-card--gisele-training,
.work-card--evoline-live,
.work-card--saloonix-live,
.work-card--cafeconart-live {
  color: #f4f7fa;
  background:
    linear-gradient(180deg, rgba(255, 222, 163, 0.09), transparent 25%),
    #292f38;
}

.work-card--featured .work-card-top {
  color: #aebdcd;
}

.work-card--featured h3 {
  color: #f7f8fa;
}

.work-card--featured p {
  color: #c6d0db;
}

.work-card--featured li {
  background: rgba(255, 255, 255, 0.09);
  color: #dce5ed;
}

.work-card--featured .work-link {
  color: #fff2d4;
}

.work-card--featured::after {
  border-color: rgba(239, 203, 128, 0.28);
}

/* Real mobile screens are mounted inside one consistent orange iPhone shell. */
.work-card--screened {
  --screen-scale: 1;
}

.work-card--screened .work-cover {
  transform: none !important;
}

.work-card--screened .work-cover span {
  display: none;
}

/* The old home-indicator bar is repurposed as a bottom edge vignette for
   real screenshots — same pseudo-element real estate, a darkening instead
   of a UI element, adding the screen-curvature depth a flat photo lacks. */
.work-card--screened .work-cover::after {
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 3;
  height: 90px;
  border: 0;
  border-radius: 0 0 31px 31px;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.32), transparent);
  box-shadow: none;
}

/* A real device has a camera dot, not a wide notch bar — the old ::before
   notch clashed with real screenshots that already show their own status
   bar, so screened cards get a small realistic camera lens instead. */
.work-card--screened .work-cover::before {
  top: 10px;
  left: 50%;
  z-index: 4;
  width: 8px;
  height: 8px;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #454b57, #05070a 72%);
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.08),
    inset 0 0 2px rgba(255, 255, 255, 0.3);
}

.work-card--screened .work-cover img {
  object-fit: cover;
  transform: none;
}

.work-card--screened:hover .work-cover img {
  transform: none;
}

/* 6 featured cards = a clean 3-per-row, 2-row grid. The earlier
   grid-column overrides here (centring a lone pair on row 2, for when
   there were only 5 cards) now break symmetry — dropped. If the card
   count goes back to a non-multiple of 3, re-add a count-specific
   centring rule rather than leaving flowed cards with an empty column. */

.work-card--featured .work-card-top,
.work-card--featured h3,
.work-card--featured p,
.work-card--featured ul,
.work-card--featured .work-link {
  position: relative;
  z-index: 1;
}

.work-card--featured .work-cover { position: relative; z-index: 1; }

/* The cards read as curated digital exhibits, not generic product tiles. */
.work-card--featured::after {
  z-index: 0;
  right: 10px;
  bottom: 10px;
  left: 10px;
  width: auto;
  height: auto;
  border: 1px solid rgba(130, 85, 23, 0.24);
  border-radius: 6px;
  opacity: 1;
}

.work-card--featured:hover {
  box-shadow:
    0 0 0 2px #10243b,
    0 0 0 4px rgba(255, 218, 140, 0.95),
    0 26px 52px rgba(0, 0, 0, 0.42),
    0 0 36px rgba(220, 166, 59, 0.2),
    inset 0 0 0 1px rgba(255, 255, 255, 0.75);
}

.selected-work.museum-motion-ready .work-card--featured {
  opacity: 0;
  transform: perspective(1200px) translate3d(0, 42px, 0) rotateX(2deg) rotate(var(--gallery-tilt, 0deg));
}

.selected-work.museum-motion-ready.is-revealed .work-card--featured {
  opacity: 1;
  transform: perspective(1200px) translate3d(0, 0, 0) rotate(var(--gallery-tilt, 0deg));
}

.selected-work.museum-motion-ready.is-revealed .work-card--featured:nth-child(2) {
  transition-delay: 0.09s;
}

.selected-work.museum-motion-ready.is-revealed .work-card--featured:nth-child(3) {
  transition-delay: 0.18s;
}

.selected-work.museum-motion-ready.is-revealed .work-card--featured:nth-child(4) {
  transition-delay: 0.27s;
}

.selected-work.museum-motion-ready.is-revealed .work-card--featured:nth-child(5) {
  transition-delay: 0.36s;
}

.selected-work.museum-motion-ready.is-revealed .work-card--featured:nth-child(6) {
  transition-delay: 0.45s;
}

.work-card--featured.is-tilting {
  transform: perspective(1200px) translate3d(0, -8px, 0) rotateX(var(--museum-rotate-x, 0deg)) rotateY(var(--museum-rotate-y, 0deg)) rotate(var(--gallery-tilt, 0deg)) !important;
}

@keyframes museum-wall-breathe {
  0% { filter: brightness(0.96) saturate(0.9); }
  100% { filter: brightness(1.08) saturate(1.04); }
}

@keyframes museum-light-pass {
  0%, 100% { opacity: 0.44; }
  52% { opacity: 0.92; }
}

@keyframes exhibit-light {
  from { opacity: 0.48; transform: translateY(-14px) scaleX(0.92); }
  to { opacity: 0.9; transform: translateY(0) scaleX(1.04); }
}

.work-cover {
  position: relative;
  display: block !important;
  width: min(238px, 72%) !important;
  height: 460px;
  margin: 0 auto 28px !important;
  padding: 0 !important;
  overflow: hidden;
  border: 10px solid transparent !important;
  border-radius: 41px;
  /* A brushed-metal gradient reads as a real case; a flat fill read as
     painted plastic/toy-like against the real screenshots it frames. */
  background:
    linear-gradient(#111827, #111827) padding-box,
    linear-gradient(155deg, #ffcfa3 0%, #ff8a4d 22%, #ff6928 45%, #c8430f 68%, #ff9a5c 100%) border-box;
  color: #fff !important;
  isolation: isolate;
  box-shadow:
    0 2px 0 rgba(255, 214, 179, 0.65) inset,
    0 -2px 0 rgba(120, 40, 10, 0.55) inset,
    0 30px 44px rgba(30, 12, 4, 0.38),
    0 10px 18px rgba(74, 27, 10, 0.26),
    0 5px 0 #b93a10;
  transform: rotate(-1.6deg);
  transition:
    transform 0.42s cubic-bezier(0.2, 0.7, 0.2, 1),
    box-shadow 0.42s ease;
}

.work-card:nth-child(even) .work-cover {
  transform: rotate(1.6deg);
}

.work-cover::before {
  content: "";
  position: absolute;
  z-index: 3;
  top: -1px;
  left: 50%;
  width: 45%;
  height: 20px;
  border-radius: 0 0 14px 14px;
  background: #171717;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.13);
}

.work-cover::after {
  position: absolute;
  z-index: 2;
  right: 9px;
  bottom: 9px;
  left: 9px;
  height: 33px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 17px;
  background: rgba(8, 12, 18, 0.86);
  content: "";
  box-shadow: 0 4px 13px rgba(0, 0, 0, 0.24);
}

.work-cover img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  transform: scale(var(--screen-scale, 1));
  transform-origin: top center;
  transition: transform 0.55s cubic-bezier(0.2, 0.7, 0.2, 1);
  /* Real device screenshots come back slightly flat/desaturated once
     scaled down into a card — a small, deliberate boost makes them read
     as vivid on-screen colour instead of a dull photo of a phone. */
  filter: saturate(1.14) contrast(1.05) brightness(1.02);
}

/* A soft diagonal glass reflection over the screenshot — the cue that makes
   a flat image inside a frame read as an actual lit glass screen instead of
   a printed photo. `screen` blend mode only lightens, so this layer is kept
   to the highlight alone; the matching edge vignette lives on ::after
   below, where a normal blend can actually darken. */
.screen-glare {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(115deg, rgba(255, 255, 255, 0.22) 0%, rgba(255, 255, 255, 0.06) 16%, transparent 32%, transparent 100%);
  mix-blend-mode: screen;
}

.work-card--gisele-home .work-cover img {
  object-position: 54% 42%;
}

.work-card--gisele-training .work-cover img {
  object-position: center 24%;
}

.work-card--evoline-live .work-cover img {
  object-position: center 48%;
}

.work-card:hover .work-cover {
  transform: translateY(-7px) rotate(0deg);
}

.work-card:hover .work-cover img {
  transform: scale(calc(var(--screen-scale, 1) + 0.025));
}

.work-cover span {
  position: absolute;
  z-index: 3;
  right: 50%;
  bottom: 17px;
  transform: translateX(50%);
  max-width: calc(100% - 20px);
  overflow: hidden;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  box-shadow: none;
  text-overflow: ellipsis;
  white-space: nowrap;
  font:
    700 9px Manrope,
    Arial,
    sans-serif;
  letter-spacing: 0.075em;
  text-transform: uppercase;
}

.work-card--featured h3 {
  margin: 0 0 10px;
  font-size: clamp(27px, 3.1vw, 38px);
}

.work-card--featured p {
  font-size: 12.5px;
}

.work-card--featured .work-link {
  margin-top: auto;
}

@media (max-width: 1080px) {
  .work-grid--featured {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .work-card--featured,
  .work-card--evoline-live,
  .work-card--saloonix-live {
    grid-column: auto;
  }
}

@media (max-width: 760px) {
  .selected-work {
    padding: 78px 0 90px;
  }
  .selected-work::before {
    height: 420px;
    background-position: center, center top;
    background-size: cover, cover;
    background-attachment: scroll, scroll;
  }
  .work-heading {
    grid-template-columns: 1fr;
    gap: 18px;
    margin-bottom: 34px;
  }
  .work-heading .section-index {
    width: max-content;
    min-height: 0;
    margin: 0;
    padding: 8px 13px;
    writing-mode: initial;
    transform: none;
  }
  .work-heading > div {
    grid-template-columns: 1fr;
    gap: 23px;
  }
  .work-heading h2 {
    grid-column: auto;
    font-size: 42px;
    padding: 0;
  }
  .work-heading p:last-child {
    grid-column: auto;
    justify-self: stretch;
    max-width: 36rem;
    margin: 0;
    padding-left: 17px;
    font-size: 14px;
  }
  .work-grid {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  .work-grid--featured {
    grid-template-columns: 1fr;
  }
  .work-card {
    min-height: 285px;
    padding: 21px;
    border-radius: 22px;
  }
  .work-card--featured {
    min-height: 710px;
    padding: 24px 24px 27px;
    border-width: 6px;
  }
  .work-card--featured::before { height: 126px; animation-duration: 9s; }

  .selected-work::before,
  .selected-work::after { animation-duration: 20s; }
  .selected-work-inner::before { top: 42px; right: -42vw; width: 86vw; height: 86vw; }
  .work-card--featured.is-tilting { transform: none !important; }
  .work-cover {
    width: min(245px, 75%) !important;
    height: 475px;
    margin: 0 auto 25px !important;
    border-width: 10px !important;
    border-radius: 41px;
    box-shadow:
      0 3px 0 #ffb087 inset,
      0 -3px 0 #b9370f inset,
      0 24px 32px rgba(74, 27, 10, 0.22),
      0 5px 0 #c64216;
  }
}

@media (prefers-reduced-motion: reduce) {
  .selected-work::before,
  .selected-work::after,
  .work-card--featured { animation: none !important; transition: none !important; }
}

/* === production-hardening.css === */
/* Production guardrails: keyboard clarity and readable mobile form controls. */
:where(a,button,input,textarea,select):focus-visible {
  outline: 3px solid #ffcf43;
  outline-offset: 3px;
}

.project-form label > span { font-size: 12px; }
.project-form input:not([type=checkbox]),
.project-form textarea,
.project-form select { font-size: 14px; }

.chat-panel[aria-hidden="true"],
.privacy-modal[aria-hidden="true"] { visibility: hidden; }

.form-status[data-state="error"] { color: #a61b31 !important; }
.form-status[data-state="success"] { color: #087d4b !important; }

/* === mobile-polish.css === */
/* Final responsive pass: preserve the art direction while giving every element
   a deliberate place on small screens. Loaded last on purpose. */

html,
body {
  max-width: 100%;
  /* overflow-x: clip (not hidden) on the root scroller broke Lenis: Lenis
     drives scroll via window.scrollTo() every rAF tick, and Chrome silently
     no-ops that call while html/body carry `clip` on this axis, so Lenis's
     internal animatedScroll kept advancing while window.scrollY sat frozen
     at 0 until a raw native scroll event forced a resync/jump. `hidden`
     clips the same horizontal bleed without that scrollTo interaction bug. */
  overflow-x: hidden;
}

@media (max-width: 760px) {
  :root {
    --mobile-gutter: 18px;
  }

  .site-shell,
  main,
  .hero,
  .world,
  .selected-work,
  .footer {
    min-width: 0;
  }

  .wrap {
    width: calc(100% - (var(--mobile-gutter) * 2)) !important;
  }

  .topbar {
    width: calc(100% - (var(--mobile-gutter) * 2)) !important;
    height: 68px;
  }

  .brand {
    gap: 7px;
    font-size: 9px;
    letter-spacing: 0.13em;
  }

  .brand img {
    width: 33px;
    height: 33px;
  }

  .topbar nav {
    gap: 8px;
  }

  .topbar nav > a {
    font-size: 11px;
  }

  .city-image {
    object-position: 57% center;
  }

  .hero-layout {
    min-height: 0 !important;
    padding: 112px 0 112px !important;
    display: grid !important;
    grid-template-columns: minmax(0, 1fr) !important;
    align-items: start !important;
    gap: 28px !important;
  }

  .hero-copy {
    min-width: 0;
    max-width: 100%;
  }

  .eyebrow {
    margin-bottom: 17px;
    font-size: 9px;
  }

  .hero h1 {
    max-width: 9.5ch;
    font-size: clamp(45px, 13.1vw, 59px) !important;
    line-height: 0.91 !important;
    letter-spacing: -0.075em !important;
    overflow-wrap: anywhere;
  }

  .hero-lede {
    max-width: 33ch;
    margin: 20px 0 15px !important;
    font-size: 14px !important;
    line-height: 1.55 !important;
  }

  .bespoke-line {
    max-width: 33ch;
    font-size: 11px;
    line-height: 1.55;
  }

  .hero-actions {
    margin-top: 21px;
  }

  .button {
    min-height: 48px;
    padding-inline: 16px;
    font-size: 11px;
  }

  .system-card {
    width: 100% !important;
    max-width: 100%;
    margin: 0 !important;
    padding: 16px;
    align-self: stretch !important;
  }

  .system-card code {
    padding: 14px 0;
    font-size: 11px;
    line-height: 1.55;
  }

  .hero-bottom {
    bottom: 22px;
    width: calc(100% - (var(--mobile-gutter) * 2)) !important;
    font-size: 8px;
  }

  .world.tile-experience {
    padding: 72px var(--mobile-gutter) 78px !important;
  }

  .tile-copy {
    width: 100%;
    max-width: 100%;
    min-width: 0;
  }

  .tile-experience .section-index {
    width: max-content;
    max-width: 100%;
    margin-bottom: 21px;
  }

  .tile-intro {
    display: grid !important;
    grid-template-columns: minmax(0, 1fr) !important;
    gap: 22px !important;
  }

  .tile-intro h2 {
    width: 100%;
    max-width: 100%;
    margin: 0;
    padding: 18px 16px 20px !important;
    font-size: clamp(39px, 11.8vw, 52px) !important;
    line-height: 0.92 !important;
    letter-spacing: -0.072em !important;
  }

  .tile-intro > p {
    width: 100%;
    max-width: 100%;
    margin: 0 !important;
    padding: 16px !important;
    font-size: 13px !important;
    line-height: 1.55 !important;
  }

  .tech-stream {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    width: 100%;
    max-width: 100% !important;
    gap: 12px 10px !important;
    margin-top: 30px !important;
  }

  .tech-stream span {
    display: flex !important;
    width: 100% !important;
    min-width: 0;
    min-height: 45px;
    height: auto !important;
    padding: 8px 8px !important;
    align-items: center;
    justify-content: center;
    overflow-wrap: anywhere;
    text-align: center;
    font-size: 9px !important;
    line-height: 1.18;
    white-space: normal !important;
  }

  .tile-note,
  .made-to-measure {
    max-width: calc(100% - 8px);
  }

  .tile-note {
    margin-top: 27px !important;
    font-size: 9px !important;
  }

  .made-to-measure {
    margin-top: 22px !important;
    padding: 16px !important;
    font-size: 13px !important;
    line-height: 1.5 !important;
  }

  

  .selected-work {
    padding: 76px 0 98px !important;
  }

  .work-heading {
    margin-bottom: 34px !important;
  }

  .work-heading h2 {
    font-size: clamp(39px, 11.7vw, 50px) !important;
    line-height: 0.94 !important;
  }

  .work-heading > div > p {
    font-size: 13px !important;
    line-height: 1.55 !important;
  }

  .work-grid--featured {
    gap: 18px !important;
  }

  .work-card {
    min-width: 0;
  }

  .work-cover {
    min-height: 285px;
  }

  .work-cover img {
    max-width: 196px;
  }

  .footer {
    width: 100% !important;
    min-height: 0 !important;
    padding: 34px 22px 198px !important;
  }

  .footer p:not(.footer-kicker) {
    max-width: 28ch;
  }

  .quick-actions {
    right: 12px !important;
    bottom: max(12px, env(safe-area-inset-bottom)) !important;
    gap: 8px !important;
    align-items: flex-end !important;
  }

  .quick-actions .whatsapp {
    display: none;
  }

  .assistant-launch {
    width: 116px !important;
    min-height: 125px !important;
  }

  .assistant-launch::before {
    width: 132px !important;
    height: 132px !important;
    bottom: -10px !important;
  }

  .assistant-launch::after {
    bottom: 111px !important;
    padding: 6px 8px !important;
    font-size: 8px !important;
  }

  .cookie-bar {
    z-index: 34;
    left: 12px !important;
    bottom: max(12px, env(safe-area-inset-bottom)) !important;
    width: calc(100% - 144px) !important;
    max-width: 238px;
    min-height: 64px;
    padding: 10px 11px !important;
    border-radius: 15px !important;
    gap: 8px !important;
    align-items: flex-start !important;
  }

  .cookie-bar p {
    font-size: 8px !important;
    line-height: 1.35 !important;
  }

  .cookie-bar div {
    display: grid !important;
    grid-template-columns: 1fr 1fr;
    width: 100%;
    gap: 5px !important;
    white-space: normal !important;
  }

  .cookie-bar button {
    min-height: 26px;
    padding: 5px !important;
    font-size: 8px !important;
  }

  .chat-panel {
    top: max(10px, env(safe-area-inset-top)) !important;
    right: 10px !important;
    bottom: 10px !important;
    width: calc(100% - 20px) !important;
    max-height: none !important;
    padding: 16px !important;
    border-radius: 24px !important;
  }

  .assistant-stage {
    min-height: 128px !important;
  }
}

@media (max-width: 360px) {
  .hero h1 { font-size: 43px !important; }
  .tech-stream { gap: 9px 8px !important; }
  .tech-stream span { font-size: 8px !important; }
  .cookie-bar { width: calc(100% - 136px) !important; }
  .assistant-launch { width: 108px !important; }
}

@media (prefers-reduced-motion: reduce) {
  .city-image,
  .assistant-launch::before,
  .assistant-scene,
  
}

/* === cinema.css === */
/* Cinematic motion pass: curtain-rise entrance + tile-fill scroll reveal.
   Safety model: the curtain clears itself via a plain CSS animation even with
   zero JS; cinema.js only takes over the timing once GSAP is confirmed loaded.
   Tile-fill entrance states are set by GSAP inline (gsap.from), never in CSS,
   so a JS failure leaves that section exactly as visible as it is today. */

/* Pre-existing bug, unrelated to any motion work: city.js sets `cookie.hidden
   = true` on Accept, but city.css's `.cookie-bar{display:flex}` and the
   `[hidden]` UA-stylesheet rule both carry the same specificity — the later
   author rule keeps winning, so the banner never actually disappeared after
   Accept. Scoping the override to `.cookie-bar[hidden]` beats the plain
   class selector and fixes this without touching city.css. */
.cookie-bar[hidden] {
  display: none !important;
}

.curtain-rise {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #06142a;
  pointer-events: none;
  animation: curtainAutoClear 2.4s ease forwards;
}

.curtain-rise-line {
  width: 0;
  max-width: 220px;
  height: 2px;
  background: linear-gradient(90deg, transparent, #ffb15b, transparent);
  box-shadow: 0 0 24px 4px rgba(255, 177, 91, 0.55);
  opacity: 0;
}

/* Loading scene: RE mark + a real CSS 3D pastel de nata + a LOADING label,
   all pure CSS keyframes (no GSAP dependency) so it's visible even before
   cinema.js confirms GSAP loaded — same zero-JS safety guarantee as
   curtainAutoClear above. Replaced the previous plain cube with a fluted
   custard tart per direct request ("um pastel de nata em 3D... estilo
   Studio Ghibli") — genuine perspective + preserve-3d construction (8 thin
   panels ringed around Y for the scalloped pastry shell, plus a custard
   disc on top with a few fixed radial-gradient blotches standing in for
   caramelised spots), not a flat sprite. No image-generation tool is
   available in this environment, so it's hand-built from gradients/shapes
   like the rest of this project's bespoke SVG/CSS scenes, not a raster
   asset — keeps the zero-image-weight discipline used everywhere else. */
.loading-scene {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}
.loading-mark {
  width: 40px;
  height: 40px;
  object-fit: contain;
  filter: brightness(0) invert(1);
  animation: loading-mark-pulse 1.6s ease-in-out infinite;
}
/* Went through several sources before landing here: a CSS-only shape, two
   licensed stock photos (Wikimedia CC BY-SA, then Pexels), and one
   ChatGPT-generated watercolour whose drawn drop-shadow kept bleeding into
   the cutout. Final asset is another user-generated (ChatGPT) illustration
   on a radial black→amber glow background instead of flat paper — a flat
   colour-distance key doesn't work on a gradient, so the cutout here is
   contour-based (OpenCV: Canny edge detection on the tart's own drawn
   outline stroke, largest closed contour filled as the mask) rather than a
   colour/background key. Own AI-generated artwork, no third-party
   licensing question. `.pastel::before` carries the actual image + the
   continuous rotateY spin ("efeito como se tivesse a girar o pastel de
   nata"); `.pastel` itself only does the vertical bob, so the two
   transforms (spin on the image, bob on its wrapper) don't fight on the
   same element. `filter:drop-shadow` (follows the real alpha silhouette,
   unlike box-shadow) grounds it against the dark curtain. */
.pastel-stage {
  width: 92px;
  height: 92px;
}
.pastel {
  display: block;
  width: 100%;
  height: 100%;
  perspective: 260px;
  animation: pastelBob 1.8s ease-in-out infinite;
}
.pastel::before {
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  background: url('pastel-de-nata.webp?v=20260820-8') center/contain no-repeat;
  filter: drop-shadow(0 10px 14px rgba(0, 0, 0, 0.5)) drop-shadow(0 0 10px rgba(255, 177, 91, 0.35));
  animation: pastelSpin 3.2s linear infinite;
}
@keyframes pastelBob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-6px); }
}
@keyframes pastelSpin {
  from { transform: rotateY(0deg); }
  to { transform: rotateY(360deg); }
}
.loading-label {
  margin: 0;
  color: #ffe4c7;
  font: 800 11px 'DM Mono', monospace;
  letter-spacing: 0.24em;
  text-transform: uppercase;
}
.loading-dots {
  display: inline-flex;
  gap: 3px;
  margin-left: 5px;
  vertical-align: middle;
}
.loading-dots i {
  display: inline-block;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: #ffb15b;
  animation: loading-dot-blink 1.1s ease-in-out infinite;
}
.loading-dots i:nth-child(2) { animation-delay: 0.15s; }
.loading-dots i:nth-child(3) { animation-delay: 0.3s; }

@keyframes loading-mark-pulse {
  0%, 100% { opacity: 0.75; transform: scale(0.96); }
  50% { opacity: 1; transform: scale(1.04); }
}
@keyframes loading-dot-blink {
  0%, 80%, 100% { opacity: 0.25; }
  40% { opacity: 1; }
}

@keyframes curtainAutoClear {
  0%,
  55% {
    opacity: 1;
    visibility: visible;
  }
  100% {
    opacity: 0;
    visibility: hidden;
  }
}

/* Once cinema.js confirms GSAP is available, it hands timing to the JS
   timeline and disables the CSS fallback animation so the two never fight. */
body.cinema-ready .curtain-rise {
  animation: none;
}

/* While the galo's GSAP entrance is in control of its transform, its CSS
   idle-breathing keyframe (galo-and-grid.css) must yield — CSS animations
   otherwise always win the cascade over an inline transform, even after the
   tween completes. cinema.js toggles this class around the entrance. */


/* Same handoff trick as the galo's tile-fill entrance, applied to the chat
   panel's galo scene while the Sync Beacon success settle plays (form-flow.js)
   or the galo easter egg wiggle plays (cinema.js). Chained to match/beat the
   specificity of the rules being overridden (contact-refinement.css) rather
   than relying on cascade source order. */
.chat-panel.is-open .assistant-scene.is-sync-settling {
  animation: none;
}

.chat-panel.is-open .assistant-avatar.is-sync-settling {
  animation: none;
}

/* Desktop-only scroll depth cue for the tile section (see cinema.js).
   Reuses the existing ::after soft-light layer from tile-experience.css —
   only adds a scroll-driven transform on top of it, no new DOM. */
@media (min-width: 769px) {
  body.cinema-ready .world.tile-experience::after {
    transform: translate3d(0, calc(var(--tile-scroll, 0) * -26px), 0);
  }
}

/* Film grain: a tiled SVG turbulence data-URI, not a raster asset — zero extra
   image weight, the exact guardrail this project already flags for the hero
   PNGs. Opacity is intentionally faint; this is texture, not a visible layer. */
.grain-overlay {
  position: fixed;
  inset: -60px;
  z-index: 9998;
  pointer-events: none;
  opacity: 0.035;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 120px 120px;
  animation: grainShift 1s steps(4) infinite;
}

@keyframes grainShift {
  0% { transform: translate(0, 0); }
  25% { transform: translate(-20px, 10px); }
  50% { transform: translate(15px, -15px); }
  75% { transform: translate(-10px, -20px); }
  100% { transform: translate(0, 0); }
}

/* Split-text hero title: each word is its own inline-block so GSAP can
   translate/opacity it independently. Neutral until cinema.js runs the
   reveal — if JS never fires the words simply sit flush, no gap, no offset. */
.hero-word {
  display: inline-block;
  will-change: transform, opacity;
}

/* Nav hover: a wipe underline, not a color swap — cheap CSS, no GSAP needed.
   header nav a in city.css sets color/weight but never position, so this adds
   the positioning context rather than fighting an existing rule for it. */
header nav a {
  position: relative;
}
header nav a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -4px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.3s ease;
}
header nav a:hover::after,
header nav a:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left;
}

/* Custom cursor: desktop fine-pointer only (see wireCustomCursor in cinema.js).
   Native cursor stays untouched everywhere else — touch, coarse pointer,
   reduced-motion — so this is pure addition, never a dependency. */
@media (hover: hover) and (pointer: fine) {
  body.cinema-ready.has-custom-cursor,
  body.cinema-ready.has-custom-cursor a,
  body.cinema-ready.has-custom-cursor button {
    cursor: none;
  }
}
.cursor-dot,
.cursor-ring {
  position: fixed;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: 10000;
  transform: translate3d(-50%, -50%, 0);
  border-radius: 50%;
}
.cursor-dot {
  width: 6px;
  height: 6px;
  background: #ffb15b;
}
.cursor-ring {
  width: 30px;
  height: 30px;
  border: 1px solid rgba(255, 255, 255, 0.55);
  transition: width 0.25s ease, height 0.25s ease, border-color 0.25s ease;
}
.cursor-ring.is-hovering {
  width: 52px;
  height: 52px;
  border-color: #ffb15b;
}

/* Azulejo Aperture: a pinned scene-transition between Hero and O Estúdio.
   Reuses the tile section's own azulejo-texture.png (already loaded for that
   section) rather than a new asset — zero added image weight. Bookends the
   hero the way the curtain-rise opened it: dark seam in, azulejo iris out —
   the same directorial device, brand-specific instead of generic. */
/* Azulejo Aperture, take two: a cinematic vignette closing in on the hero,
   not a circle of tile pattern opening up. A textured "porthole" read as
   busy/cheap; a soft dark iris closing toward the frame's own night tone
   (matching .curtain-rise's #06142a) reads as an actual camera device, and
   bookends the entrance's dark curtain with a matching close mid-page.
   --iris-r is the vignette's transparent inner radius, tweened by
   wireApertureTransition() in cinema.js: 140% (invisible, off past every
   corner) down to 0% (fully closed) and back to invisible via opacity. */
.aperture-iris {
  position: fixed;
  inset: 0;
  z-index: 40;
  pointer-events: none;
  display: none;
  background: radial-gradient(circle at 50% 50%, transparent var(--iris-r, 140%), rgba(6, 20, 42, 0.97) calc(var(--iris-r, 140%) + 42%));
}
body.cinema-ready .aperture-iris {
  display: block;
}

/* Azulejo medallion: hand-drawn line-art anchor for O Estúdio, so the section
   has real illustrated weight instead of only text cards on a flat tile
   pattern. Positioned behind the copy (z-index:-1 within .tile-copy's own
   stacking context, which is z-index:1 — negative still stacks under normal
   siblings there), bleeding off the right edge; .world.tile-experience's own
   overflow:hidden clips the bleed cleanly at the section boundary. */
.azulejo-medallion {
  position: absolute;
  top: 6%;
  right: -40px;
  z-index: -1;
  width: 440px;
  height: 440px;
  color: #f06c28;
  opacity: 0.85;
  pointer-events: none;
  /* A soft cream "clearing" behind the linework — without it the medallion
     is the same cool-blue family as the dense azulejo photo texture behind
     it and reads as nothing; this gives it a plate to sit on, like a real
     inset ceramic medallion, and the warm ember stroke pops against both
     the blue tiles and the clearing itself. */
  filter: drop-shadow(0 0 46px rgba(245, 240, 225, 0.9)) drop-shadow(0 0 22px rgba(245, 240, 225, 0.9));
}
.medallion-shape {
  will-change: stroke-dashoffset;
}
@media (max-width: 760px) {
  /* top must stay >= 0: a negative value here pulls the medallion above
     .world.tile-experience's own top edge — its own overflow:hidden can't
     save it, because .hero and .tile-experience are separate stacking
     contexts (each isolation:isolate) and paint order between them follows
     DOM order regardless of the medallion's z-index:-1, which only controls
     stacking *within* tile-experience. A short mobile hero made this overlap
     visible: the medallion rendered on top of the hero's CTA button. */
  .azulejo-medallion {
    top: 0;
    right: -110px;
    width: 300px;
    height: 300px;
    opacity: 0.75;
    /* The desktop drop-shadow's blur radius (46px+22px) visually bleeds well
       beyond the element's own box — getBoundingClientRect only reports the
       layout box, not the filter's paint bounds, so this glow was reaching
       up into the hero's CTA button despite the element itself being fully
       contained in .world.tile-experience. Shrunk for the smaller mobile
       medallion so the halo stays inside the section it belongs to. */
    filter: drop-shadow(0 0 18px rgba(245, 240, 225, 0.9)) drop-shadow(0 0 8px rgba(245, 240, 225, 0.9));
  }
}

/* Footer skyline: a line-art negative of the hero's painted city, bookending
   the site's day/night motif at its close. Sits behind .footer's own content
   (which is already z-index:1 per footer-refresh.css). Windows start dim
   (visible even with zero JS) and brighten on scroll-entry, never starting
   from fully invisible. */
.footer-skyline {
  position: absolute;
  z-index: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 130px;
  color: rgba(157, 203, 255, 0.4);
  pointer-events: none;
}
.skyline-lights circle {
  opacity: 0.22;
  will-change: opacity;
}

/* Atmosphere glow: one soft radial wash that drifts with overall scroll
   progress, giving the page a single continuous mood instead of each section
   being visually self-contained. Blend is intentionally mild — legible over
   the dark hero/footer, nearly invisible over the light azulejo section,
   which reads as ambient light rather than a flat tint everywhere. */
.atmosphere-glow {
  position: fixed;
  inset: 0;
  z-index: 3;
  overflow: hidden;
  pointer-events: none;
}
.atmosphere-glow::before {
  content: '';
  position: absolute;
  left: 50%;
  top: calc(var(--atmosphere-y, 20) * 1%);
  width: 820px;
  height: 820px;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, rgba(12, 71, 143, 0.16), rgba(240, 108, 40, 0.09) 55%, transparent 72%);
  filter: blur(90px);
}

/* Project-grid spotlight: a beam of light that travels down the section as
   you scroll, landing on whichever project is currently in view — driven by
   scroll progress so it works on touch devices too, with cursor-follow on
   the X axis as a fine-pointer bonus (see wireGridSpotlight in cinema.js). */
.grid-spotlight {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(620px circle at var(--spot-x, 50%) var(--spot-y, 8%), rgba(240, 108, 40, 0.22), transparent 70%);
  transition: opacity 0.6s ease;
}
.grid-spotlight.is-active {
  opacity: 1;
}

/* The project actually under the beam brightens and lifts slightly, so the
   light reads as illuminating it rather than just tinting the background. */
.work-grid--featured .work-card {
  transition:
    box-shadow 0.6s ease,
    filter 0.6s ease,
    transform 0.6s ease;
}
.work-grid--featured .work-card.is-lit {
  filter: brightness(1.04);
  box-shadow:
    0 0 0 2px #10243b,
    0 0 0 4px rgba(239, 203, 128, 0.86),
    0 26px 54px rgba(240, 108, 40, 0.22),
    0 18px 36px rgba(0, 0, 0, 0.3),
    inset 0 0 0 1px rgba(255, 255, 255, 0.65);
}

@media (prefers-reduced-motion: reduce) {
  .aperture-iris {
    display: none !important;
  }
  .azulejo-medallion .medallion-shape {
    stroke-dashoffset: 0 !important;
  }
  .skyline-lights circle {
    opacity: 0.55 !important;
  }
  .grid-spotlight {
    display: none !important;
  }
  .curtain-rise,
  .curtain-rise-line,
  .pastel-stage,
  .pastel,
  .pastel::before,
  .loading-mark,
  .loading-dots i {
    animation: none !important;
  }
  .curtain-rise {
    opacity: 0 !important;
    visibility: hidden !important;
  }
  .grain-overlay {
    animation: none !important;
    opacity: 0.02;
  }
}

/* === cosmos.css === */
/* Azulejo Cosmos: a WebGL tile field scoped to the Selected Work section only
   (see cosmos.js — it fades canvas opacity in/out based on that section's
   scroll position, not a page-wide tunnel any more). Previously ran behind
   the entire page, which read as visual noise everywhere else ("polui todo
   website" — direct feedback); the canvas itself stays fixed full-viewport
   (a 3D scene can't be clipped to a section without a second render target),
   but is invisible outside that section's scroll range. Falls back to
   nothing here — cinema.css's .atmosphere-glow stays mounted and visible
   whenever cosmos.js can't run (no WebGL, JS disabled, prefers-reduced-motion)
   or when scrolled outside the Selected Work section, so the rest of the page
   always has ambient light instead of a gap. */
.cosmos-canvas {
  position: fixed;
  inset: 0;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
}
/* Lives inside .selected-work now (moved from body-level) so it paints
   within that section's own isolated stacking context: after the
   section's opaque background, but before .selected-work-inner's
   z-index:1 content (cards, text) — visible against the dark backdrop
   without ever drawing over the project cards. .selected-work > *
   would otherwise force position:relative/z-index:1 onto it like any
   other direct child, so this reasserts fixed positioning + a lower
   z-index explicitly. */
.selected-work > .cosmos-canvas {
  position: fixed;
  z-index: 0;
}

/* Only hides the flat CSS fallback while the tile field is actually visible
   (cosmos.js toggles this class based on canvas opacity, not just WebGL
   support) — everywhere else on the page keeps the ambient glow. */
body.has-cosmos .atmosphere-glow {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .cosmos-canvas {
    display: none !important;
  }
}

/* === pricing.css === */
.pricing {
  position: relative;
  padding: 96px max(20px, calc((100% - 1180px) / 2)) 40px;
  background: #06142a;
  color: #fff;
}
.pricing-heading {
  max-width: 640px;
  margin: 0 0 48px;
}
.pricing-heading h2 {
  margin: 10px 0 14px;
  font-size: clamp(28px, 4vw, 42px);
  letter-spacing: -0.03em;
  color: #fff;
}
.pricing-heading p {
  color: rgba(255, 255, 255, 0.72);
  font-size: 16px;
  line-height: 1.55;
}
.pricing-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 18px;
}
.pricing-card {
  position: relative;
  padding: 26px 22px 28px;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.14);
  display: flex;
  flex-direction: column;
}
.pricing-card--highlight {
  background: rgba(240, 108, 40, 0.12);
  border-color: rgba(240, 108, 40, 0.55);
}
.pricing-card--custom {
  background: rgba(255, 255, 255, 0.03);
  border-style: dashed;
}
.pricing-badge {
  position: absolute;
  top: -12px;
  left: 22px;
  padding: 4px 10px;
  border-radius: 999px;
  background: #f06c28;
  color: #06142a;
  font: 700 10px "DM Mono", monospace;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.pricing-price {
  font: 800 34px/1 Manrope, sans-serif;
  letter-spacing: -0.02em;
  margin: 6px 0 4px;
  color: #fff;
}
.pricing-card h3 {
  margin: 0 0 14px;
  font-size: 17px;
  color: #fff;
}
.pricing-card ul {
  list-style: none;
  margin: 0 0 20px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 9px;
  flex: 1;
}
.pricing-card li {
  padding-left: 18px;
  position: relative;
  font-size: 13.5px;
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.82);
}
.pricing-card li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 7px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #f06c28;
}
.pricing-card--custom p:not(.pricing-price) {
  font-size: 13.5px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.78);
  margin: 0 0 18px;
}
.pricing-card .button-secondary {
  align-self: flex-start;
  border: 1px solid rgba(255, 255, 255, 0.4);
  background: transparent;
  color: #fff;
}
.lang-switch {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 6px;
  padding-left: 12px;
  border-left: 1px solid rgba(255, 255, 255, 0.2);
}
.lang-switch a {
  padding: 4px 7px;
  font: 700 11px "DM Mono", monospace;
  letter-spacing: 0.03em;
  border-radius: 6px;
  color: rgba(255, 255, 255, 0.6);
}
.lang-switch a:hover {
  color: #fff;
}
.lang-switch a[aria-current="page"] {
  color: #fff;
  background: rgba(255, 255, 255, 0.14);
}
@media (max-width: 760px) {
  .pricing {
    padding: 64px 19px 24px;
  }
  .pricing-grid {
    grid-template-columns: 1fr;
  }
}

/* === hero-implosion.css === */
/* Azulejo shards that fly in and fuse into the hero title as the curtain
   clears (cinema.js builds/animates/removes these — see the "Hero Implosion"
   block there). Sits between .city-visual (z-index:-2) and .hero-layout
   (z-index:2) inside .hero's own isolated stacking context, so shards pass
   behind the copy but in front of the painted city. One-shot: the wrapper is
   removed from the DOM once the tween completes, so there is zero ongoing
   cost after the entrance. */
.hero-implosion {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: visible;
  pointer-events: none;
}
.implosion-shard {
  position: absolute;
  left: var(--implosion-cx, 50%);
  top: var(--implosion-cy, 50%);
  border-radius: 3px;
  will-change: transform, opacity;
}
@media (prefers-reduced-motion: reduce) {
  .hero-implosion {
    display: none !important;
  }
}

/* === gallery-plaque.css === */
/* The Selected Work cards already had a gilt frame + museum-style spotlight
   lighting above them, but the real device screenshots inside still read as
   plain screen captures, not art — direct feedback ("as imagens não soam
   legal... algo mais artístico"). Three additions, all composing with the
   existing motion (museum-motion.js's tilt/reveal, cinema.js's clip-path
   cover reveal) rather than replacing it:
   1. --gallery-tilt: a small per-card baseline rotation, composed into the
      SAME transform chains those other systems already own (see the four
      `rotate(var(--gallery-tilt, 0deg))` insertions above, one per state) —
      a card can't have two independent `transform` declarations both take
      effect, so the tilt has to ride along inside each existing value
      rather than living in a rule of its own.
   2. .gallery-varnish: a warm soft-light glaze over the screenshot itself,
      unifying five real, differently-lit screenshots into one consistent
      "gallery light falling on the piece" mood instead of five clashing
      raw captures.
   3. .gallery-plaque: a small museum wall-label line under the frame. */
.work-card--featured:nth-child(odd) {
  --gallery-tilt: -0.55deg;
}
.work-card--featured:nth-child(even) {
  --gallery-tilt: 0.55deg;
}

.gallery-varnish {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background:
    radial-gradient(120% 70% at 50% 0%, rgba(255, 205, 111, 0.22), transparent 60%),
    linear-gradient(185deg, rgba(184, 138, 58, 0.16), transparent 45%, rgba(16, 36, 59, 0.3));
  mix-blend-mode: soft-light;
  opacity: 0.9;
}

.gallery-plaque {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid rgba(184, 138, 58, 0.35);
}
.gallery-plaque em {
  font-family: "Playfair Display", serif;
  font-style: italic;
  font-weight: 600;
  font-size: 13px;
  opacity: 0.92;
}
.gallery-plaque b {
  font: 700 9px "DM Mono", monospace;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.5;
}
@media (max-width: 760px) {
  .work-card--featured:nth-child(odd),
  .work-card--featured:nth-child(even) {
    --gallery-tilt: 0deg;
  }
}

/* === ios-safari-hardening.css === */
/* Fixes for iOS Safari specifically: cookie-bar text/buttons shrank to 8-9px
   across the mobile-polish and 360px breakpoints above — real, below any
   comfortable reading size, and the direct cause of "aceitar a politica
   imenso pequeno". Also: `-webkit-text-size-adjust` was never set, `100vh`
   on .chat-panel doesn't account for Safari's collapsing/expanding address
   bar (dvh does), and .cosmos-canvas — a WebGL canvas painting every frame,
   position:fixed, opacity written from JS every tick — is exactly the kind
   of layer WebKit has historically struggled to keep glued to the visual
   viewport during momentum scroll ("scrolls ficam bugado", layout
   appearing to "sair de formatação" mid-scroll). Appended last so these
   !important rules win ties against the earlier mobile breakpoints, per
   this file's existing cascade convention. */
html {
  -webkit-text-size-adjust: 100%;
}
@media (max-width: 760px) {
  /* An earlier pass bumped the font from 8px to 12px without widening the
     238px-wide bar inherited from the mobile-polish breakpoint below — at
     that width the <p> got squeezed into a ~110px column (text + buttons
     side by side) and wrapped across 7-8 lines, ballooning the bar to
     ~230px tall ("gigantesco"). Fix is the width, not the font: give the
     bar real width and stack text above buttons instead of forcing them
     side by side. */
  .cookie-bar {
    width: calc(100% - 24px) !important;
    max-width: 420px !important;
    left: 12px !important;
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 12px !important;
    min-height: 0 !important;
  }
  .cookie-bar p {
    font-size: 12px !important;
    line-height: 1.45 !important;
  }
  .cookie-bar div {
    display: flex !important;
    flex-direction: row !important;
    width: 100% !important;
    gap: 8px !important;
  }
  .cookie-bar div button {
    flex: 1 1 0;
  }
  .cookie-bar button {
    font-size: 12px !important;
    min-height: 38px !important;
    padding: 8px 12px !important;
  }
  .cookie-bar #accept-cookies {
    padding: 8px 14px !important;
  }
}
.chat-panel {
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
@supports (height: 100dvh) {
  .chat-panel {
    max-height: calc(100dvh - 110px) !important;
  }
}
.cosmos-canvas {
  transform: translateZ(0);
  -webkit-transform: translateZ(0);
  backface-visibility: hidden;
}

/* === vintage-frame.css === */
/* "sacar o iphone e por em uma moldura ... algo vintage" — the phone-mockup
   bezel (rounded 41px corners, notch, camera dot, dark home-indicator bar)
   clashed with the museum-plaque redesign applied earlier (gallery-plaque
   "Oleo sobre pixel" labels, hung-painting tilt): everything else on these
   cards reads as a framed painting, but the image itself still read as an
   iPhone product shot, worse on mobile where the extra phone chrome eats
   space the plaque/tilt treatment doesn't need. Replaced with an actual
   gallery-frame treatment — antique brass border, cream mat around the
   photo, sharp corners — and the phone-only chrome (notch/camera dot/
   home-indicator) is dropped entirely. Appended last so it wins the
   cascade over every earlier .work-cover rule without hunting each
   breakpoint that touched them. */
.work-cover {
  padding: 11px !important;
  border-radius: 5px !important;
  background:
    linear-gradient(#f1e8d3, #f1e8d3) padding-box,
    linear-gradient(155deg, #e8c078 0%, #caa055 22%, #a9793a 45%, #7a5423 68%, #c79a52 100%) border-box !important;
  box-shadow:
    0 0 0 1px rgba(58, 38, 12, 0.55),
    0 30px 44px rgba(30, 12, 4, 0.38),
    0 10px 18px rgba(74, 27, 10, 0.26) !important;
}

.work-cover img {
  border-radius: 2px;
}

/* object-fit:cover + a fixed-height frame was cropping real content (top
   nav, CTA buttons, footer edges) whenever a screenshot's aspect ratio
   didn't exactly match the frame's — "ainda aparecem meio cortadas".
   contain guarantees the whole screenshot is always visible; with the mat
   already in place from the frame above, any resulting letterbox gap reads
   as more matting, not empty space, so this fits the frame concept rather
   than fighting it. Matches `.work-card--screened .work-cover img`'s
   higher specificity (3 classes) so it actually wins instead of losing to
   source order. */
.work-card--screened .work-cover img,
.work-cover img {
  object-fit: contain !important;
  object-position: center !important;
}

.work-cover::before,
.work-cover::after,
.work-card--screened .work-cover::before,
.work-card--screened .work-cover::after {
  display: none !important;
}

@media (max-width: 760px) {
  .work-cover {
    padding: 9px !important;
    border-radius: 4px !important;
  }
}

/* === robot-mascot.css === */
/* Went through several passes: a hand-built CSS 3D robot (flat, no real
   light), a cut-out stock photo ("não parece sprite 3D"), a real lit WebGL
   character (robot-mascot.js + vendor/three.module.min.js) — then replaced
   outright ("remova esse assistente voce nao sabe criar") with the user's
   own AI-generated renders: two pre-lit, pre-posed PNGs (laptop pose for
   the launcher, waving pose for the open chat scene), cut out from their
   baked-in checkerboard background via a saturation/brightness threshold
   (Pillow, not a real alpha channel in the source) and re-exported as
   assistant-laptop.webp / assistant-wave.webp — ~80KB each versus the
   1.5-2.1MB source PNGs, and a net weight WIN over the WebGL build once
   robot-mascot.js's own three.module.min.js import is gone (cosmos.js
   still needs that vendor file for its own scene, so it stays on disk).
   Plain <img class="robot-img"> in both spots now, no JS mount step at
   all — the ::before radial-gradient orb behind it is no longer a
   fallback-only layer (no .has-robot-canvas gate), it's a permanent ambient
   glow every visitor sees, WebGL or not. */
.assistant-launch {
  appearance: none;
  -webkit-appearance: none;
}

/* === assistant-premium.css === */
/* Assistant premium pass: a real state machine (assistant-state.js sets
   [data-assistant-state] on <html>), a badge that replaces the old
   always-on ::after text label (that content was baked into CSS, invisible
   to tools/build_locales.py — a real DOM element lets the badge's "online"
   word go through the site's existing data-i18n pipeline), and quick-action
   chips above the lead-wizard's first step. State color accents are applied
   here via CSS custom properties, not new keyframes, so a reduced-motion or
   no-WebGL visitor still sees the badge dot and fallback orb change color
   per state — only the *motion* is gated below, never the state signal. */

.assistant-launch::after { content: none; } /* superseded by .assistant-badge, a real (translatable) element */

/* Every selector below is prefixed with the .assistant-launch ancestor —
   not decorative scoping, but a specificity requirement: .assistant-badge
   and .assistant-badge-dot are <span> elements nested inside
   .assistant-launch, and the button already carries two generic
   `.assistant-launch span { ... display:grid; background:#fff; ... }` /
   `.assistant-launch>span { display:none }` rules from the original
   quick-actions markup (bare `span` type selector = higher specificity
   than a bare `.assistant-badge` class selector, source order can't win
   against that). Unprefixed, the badge silently computed display:none —
   this is the exact cascade gotcha CLAUDE.md documents elsewhere in this
   project, just hitting a new element instead of an animated transform. */
.assistant-launch .assistant-badge {
  position: absolute;
  z-index: 2;
  /* Centered over the image's own head, not the button — the robot's head
     sits right of the image's horizontal center; a badge centered on the
     button read as floating over the laptop, not "above the head" (direct
     feedback). Offset is the head's own measured x-fraction (~0.774 of
     image width) times the image's rendered width. */
  left: calc(50% + 36px);
  bottom: 156px;
  transform: translateX(-50%) translateY(4px);
  display: flex;
  align-items: center;
  gap: 6px;
  width: max-content;
  max-width: 152px;
  padding: 7px 12px;
  border: 1px solid rgba(97, 219, 255, 0.28);
  border-radius: 999px;
  /* Dark glass, not the orange gradient the old ::after label used — that
     orange sat directly on top of the robot's own orange body and read as
     a color clash/glitch, not a badge. Same navy-glass treatment as the
     curtain-rise veil and system-card elsewhere on the page. */
  background: linear-gradient(135deg, rgba(6, 20, 42, 0.92), rgba(16, 40, 66, 0.92));
  color: #f6f2e9;
  box-shadow: 0 8px 20px rgba(4, 12, 26, 0.4), inset 0 1px rgba(255, 255, 255, 0.08);
  font: 700 10px Manrope, Arial, sans-serif;
  letter-spacing: 0.01em;
  white-space: nowrap;
  opacity: 0.92;
  transition: opacity 0.22s ease, transform 0.22s ease;
  pointer-events: none;
}
.assistant-launch:hover .assistant-badge,
.assistant-launch:focus-visible .assistant-badge {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.assistant-launch .assistant-badge b { font-weight: 800; }
.assistant-launch .assistant-badge-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  /* Same green as .assistant-avatar::after's online dot in the chat-panel
     header — one "online" color across the two spots that show it, not a
     mismatched cyan here and green there. */
  background: #2bc779;
  box-shadow: 0 0 5px 1px rgba(43, 199, 121, 0.75);
  flex: 0 0 auto;
  animation: assistant-badge-pulse 2.2s ease-in-out infinite;
}
@media (max-width: 390px) {
  .assistant-launch .assistant-badge { bottom: 128px; max-width: 128px; font-size: 9px; padding: 6px 10px; }
}

/* State accents: color only, applied to whatever's actually on screen for a
   given visitor — the badge dot always exists; the fallback orbs only exist
   when robot-mascot.js's WebGL layer never mounted (reduced motion / no
   WebGL). Both read the same [data-assistant-state] attribute. */
[data-assistant-state="thinking"] .assistant-badge-dot,
[data-assistant-state="listening"] .assistant-badge-dot { background: #ffb15b; box-shadow: 0 0 5px 1px rgba(255, 177, 91, 0.75); }
[data-assistant-state="success"] .assistant-badge-dot { background: #6dffb0; box-shadow: 0 0 5px 1px rgba(109, 255, 176, 0.75); }
[data-assistant-state="error"] .assistant-badge-dot { background: #ff8a6d; box-shadow: 0 0 5px 1px rgba(255, 138, 109, 0.75); }
[data-assistant-state="thinking"] .assistant-launch::before,
[data-assistant-state="thinking"] .assistant-scene::before { background: radial-gradient(circle, rgba(255, 177, 91, 0.32), rgba(16, 52, 90, 0.14) 60%, transparent 75%); }
[data-assistant-state="success"] .assistant-launch::before,
[data-assistant-state="success"] .assistant-scene::before { background: radial-gradient(circle, rgba(109, 255, 176, 0.32), rgba(16, 52, 90, 0.14) 60%, transparent 75%); }
[data-assistant-state="error"] .assistant-launch::before,
[data-assistant-state="error"] .assistant-scene::before { background: radial-gradient(circle, rgba(255, 138, 109, 0.32), rgba(16, 52, 90, 0.14) 60%, transparent 75%); }

/* Quick-action chips: shortcuts above the wizard's own step 1, not a second
   form — see form-flow.js for what a click actually does (preselect a
   project-type radio, focus the name field; never skips a step). */
.quick-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 12px;
  position: relative;
  z-index: 2;
}
.quick-chip {
  border: 1px solid rgba(255, 255, 255, 0.28);
  background: rgba(255, 255, 255, 0.08);
  color: #f6f2e9;
  border-radius: 999px;
  padding: 7px 12px;
  font: 700 10.5px Manrope, Arial, sans-serif;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: background 0.16s ease, border-color 0.16s ease, transform 0.12s ease;
}
.quick-chip:hover,
.quick-chip:focus-visible { background: rgba(255, 255, 255, 0.18); border-color: rgba(255, 255, 255, 0.5); transform: translateY(-1px); }
.quick-chip.is-active { background: #f06c28; border-color: #f06c28; color: #142842; }

@keyframes assistant-badge-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }

@media (prefers-reduced-motion: reduce) {
  .assistant-badge-dot { animation: none !important; }
  .quick-chip { transition: none !important; }
}

/* === assistant-launcher-desktop-scale.css === */
/* The launcher button was a flat 164px regardless of viewport — on a wide
   desktop screen that reads as a stray tiny icon lost in a corner, direct
   feedback ("assistente muito pequeno... nao parece um robo"). Scaled up
   ~22% for real desktop widths only (mobile's own 116px/108px overrides at
   760px/360px are untouched) — every dependent offset (canvas, fallback
   orb, badge) scaled by the same 164->200 ratio so nothing drifts off the
   button at the new size. */
@media (min-width: 1180px) {
  .assistant-launch { width: 200px; min-height: 210px; }
  .assistant-launch::before { width: 134px; height: 134px; bottom: 17px; }
  .assistant-launch .robot-img { height: 182px; bottom: -4px; }
  .assistant-launch .assistant-badge { bottom: 188px; left: calc(50% + 43px); }
}

/* Final widget geometry: deliberately last so legacy scale passes cannot drift it. */
.quick-actions{z-index:50;right:clamp(12px,2vw,28px);bottom:max(16px,env(safe-area-inset-bottom));pointer-events:none}
.quick-actions>*{pointer-events:auto}
.assistant-launch,.assistant-launch:hover{width:158px;min-height:160px;border-radius:24px;box-shadow:none;outline-offset:5px}
.assistant-launch::before{bottom:2px;width:116px;height:116px;opacity:.78}
.assistant-launch .robot-img{bottom:0;width:148px;height:168px;object-fit:contain;object-position:center bottom;filter:drop-shadow(0 12px 12px rgba(7,22,43,.32))}
.assistant-launch .assistant-badge{right:calc(100% + 8px);left:auto;bottom:96px;max-width:132px;padding:7px 10px;background:rgba(6,20,42,.94);font-size:9px;transform:none}
.assistant-launch:hover .assistant-badge,.assistant-launch:focus-visible .assistant-badge{transform:translateY(-2px)}
.assistant-launch:focus-visible{outline:3px solid #65dfff}
.chat-panel{z-index:61;right:clamp(12px,2vw,28px);bottom:24px;max-height:min(760px,calc(100dvh - 48px));overscroll-behavior:contain;scrollbar-gutter:stable;transform-origin:bottom right}
.chat-backdrop{z-index:60;background:rgba(2,9,20,.34);backdrop-filter:blur(2px)}
.chat-panel-head{position:sticky;z-index:5;top:-20px;margin:-20px -20px 0;padding:16px 20px;background:rgba(249,248,245,.96);backdrop-filter:blur(12px)}
.chat-panel-head>button:focus-visible,.project-form :focus-visible{outline:3px solid rgba(36,108,255,.3);outline-offset:2px}
body:has(.chat-panel.is-open) .quick-actions{opacity:0;pointer-events:none}
@media(max-width:760px){
  .quick-actions{right:8px;bottom:max(8px,env(safe-area-inset-bottom))}
  .assistant-launch,.assistant-launch:hover{width:122px;min-height:132px}
  .assistant-launch .robot-img{width:116px;height:132px}
  .assistant-launch::before{width:96px;height:96px;bottom:0}
  .assistant-launch .assistant-badge{right:calc(100% + 6px);left:auto;bottom:74px;max-width:108px;padding:6px 8px;font-size:8px;transform:none}
  .chat-panel{inset:max(8px,env(safe-area-inset-top)) 8px max(8px,env(safe-area-inset-bottom));width:auto;max-height:none;border-radius:22px;padding:16px}
  .chat-panel-head{top:-16px;margin:-16px -16px 0;padding:14px 16px}
  .assistant-stage{min-height:128px}.assistant-message{width:64%;padding:14px}.assistant-scene{width:146px;height:146px}
}
@media(max-width:380px){.assistant-launch,.assistant-launch:hover{width:112px;min-height:122px}.assistant-launch .robot-img{width:106px;height:122px}.assistant-launch .assistant-badge{right:calc(100% + 5px);left:auto;bottom:68px;max-width:102px}.contact-choice,.project-choice{grid-template-columns:1fr}}

/* Portuguese travel collage replaces the former orange geometric medallion. */
.azulejo-medallion{display:none!important}
.portugal-travel-collage{position:absolute;z-index:0;top:365px;right:14px;width:clamp(230px,19vw,270px);height:auto;max-height:430px;object-fit:contain;pointer-events:none;filter:drop-shadow(0 20px 28px rgba(6,43,99,.22));transform:rotate(1.2deg)}
.tile-copy{z-index:1}
@media(max-width:1050px){.portugal-travel-collage{top:390px;right:10px;width:230px;opacity:.94}}
@media(max-width:760px){.portugal-travel-collage{display:none}.world.tile-experience{padding-bottom:70px}.azulejo-medallion{display:block!important}}

/* Hero responsive proof: a real mobile capture replaces the code card. */
.iphone-showcase{position:relative;width:clamp(285px,25vw,340px);margin:0 8px 6px auto;align-self:flex-end;display:grid;justify-items:center;filter:drop-shadow(0 28px 38px rgba(0,0,0,.34));animation:iphone-float 6s ease-in-out infinite}
.iphone-device{position:relative;width:clamp(184px,15.5vw,218px);aspect-ratio:440/956;padding:7px;border:1px solid rgba(255,255,255,.5);border-radius:42px;background:#090b10;box-shadow:inset 0 0 0 2px #343842,inset 0 0 0 5px #11141a,0 20px 55px rgba(0,0,0,.42);transform:rotate(4deg);overflow:hidden}
.iphone-device::before{content:'';position:absolute;z-index:4;left:50%;top:13px;width:34%;height:22px;transform:translateX(-50%);border-radius:999px;background:#050608;box-shadow:0 1px 0 rgba(255,255,255,.08)}
.iphone-device::after{content:'';position:absolute;z-index:3;inset:7px;border-radius:35px;background:linear-gradient(115deg,rgba(255,255,255,.16),transparent 18%,transparent 68%,rgba(255,255,255,.08));pointer-events:none}
.iphone-screen{position:absolute;inset:7px;overflow:hidden;border-radius:35px;background:#06142a}
.iphone-screen .iphone-screen-capture{position:absolute;top:0;left:50%;display:block;width:136%;max-width:none;height:auto;transform:translateX(-50%);object-fit:initial;object-position:top center}
.iphone-screen::after{content:'';position:absolute;z-index:1;inset:0;background:linear-gradient(90deg,rgba(3,13,28,.58),rgba(3,13,28,.06) 82%),linear-gradient(0deg,transparent 56%,rgba(3,13,28,.18));pointer-events:none}
.iphone-screen-title{position:absolute;z-index:2;left:13px;right:9px;top:18%;color:#fff;text-align:left;pointer-events:none;text-shadow:0 3px 14px rgba(2,10,24,.58)}
.iphone-screen-title span{display:flex;align-items:center;gap:5px;margin-bottom:10px;color:rgba(255,255,255,.84);font:600 4.8px/1.2 'DM Mono';letter-spacing:.09em;text-transform:uppercase}
.iphone-screen-title span::before{content:'';width:4px;height:4px;border-radius:50%;background:#61dbff;box-shadow:0 0 0 3px rgba(97,219,255,.14)}
.iphone-screen-title strong{display:block;font:800 clamp(16px,1.4vw,20px)/.9 Manrope,Arial,sans-serif;letter-spacing:-.07em}
.iphone-screen-title em{font-family:'Playfair Display',serif;font-weight:600}
.iphone-screen-lede{max-width:92%;margin:10px 0 0;color:rgba(255,255,255,.86);font:500 5.8px/1.45 Manrope,Arial,sans-serif;letter-spacing:0}
.iphone-screen-bespoke{max-width:94%;margin:9px 0 0;padding:6px 7px;border:1px solid rgba(255,255,255,.38);border-radius:7px;background:rgba(5,20,45,.38);color:rgba(255,255,255,.94);font:700 5.1px/1.35 'DM Mono';letter-spacing:0;backdrop-filter:blur(5px)}
.iphone-screen-title .iphone-screen-cta{display:inline-flex;width:auto;height:auto;margin-top:9px;margin-bottom:0;padding:7px 9px;align-items:center;gap:12px;border-radius:999px;background:#fff;color:#06142a;box-shadow:0 6px 15px rgba(0,0,0,.2);font:800 5.8px/1 Manrope,Arial,sans-serif;letter-spacing:0;text-transform:none}
.iphone-screen-title .iphone-screen-cta::before{content:none}
.iphone-screen-title .iphone-screen-cta b{font-size:8px}
.iphone-screen-bottom{display:block;max-width:68%;margin-top:7px;color:rgba(255,255,255,.76);font:600 4.6px/1.3 'DM Mono';letter-spacing:.055em;text-transform:uppercase}
.iphone-screen .iphone-screen-assistant{position:absolute;z-index:3;right:-3px;bottom:9px;display:block;width:49%;height:auto;max-width:none;filter:drop-shadow(0 8px 8px rgba(1,9,22,.44));transform:rotate(-1deg);pointer-events:none}
.iphone-action{display:none}
.iphone-showcase-copy{position:absolute;z-index:6;left:0;top:52%;width:156px;padding:13px 14px;border:1px solid rgba(255,255,255,.28);border-radius:16px;background:rgba(4,15,32,.78);box-shadow:0 16px 35px rgba(0,0,0,.28);backdrop-filter:blur(15px);transform:translateX(-26%) rotate(-2deg)}
.iphone-showcase-copy span{display:block;margin-bottom:7px;color:#70dcff;font:700 8px/1 'DM Mono';letter-spacing:.12em}
.iphone-showcase-copy strong{display:block;color:#fff;font:800 13px/1.15 Manrope,Arial,sans-serif;letter-spacing:-.03em}
.iphone-showcase figcaption{display:flex;align-items:center;gap:8px;margin-top:12px;color:rgba(255,255,255,.76);font:600 8px/1 'DM Mono';letter-spacing:.08em;text-transform:uppercase}
.iphone-showcase figcaption .signal{width:6px;height:6px;box-shadow:0 0 0 4px rgba(97,219,255,.12)}
@keyframes iphone-float{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}
@media(min-width:1180px){.iphone-showcase{margin-right:145px}}
@media(max-width:980px) and (min-width:761px){.iphone-showcase{width:250px}.iphone-device{width:178px}.iphone-showcase-copy{left:6px;width:138px;transform:translateX(-18%) rotate(-2deg)}.iphone-showcase-copy strong{font-size:11px}}
@media(max-width:760px){.iphone-showcase{display:none}}
@media(prefers-reduced-motion:reduce){.iphone-showcase{animation:none}}

/* Keep the pinned cinematic hero painted through the full ScrollTrigger spacer. */
.pin-spacer:has(> .hero) > .hero{height:calc(100dvh + 125px)!important;min-height:calc(100dvh + 125px)!important}
.pin-spacer:has(> .hero){margin-bottom:-86px!important}

/* Final mobile containment: padded editorial cards must stay inside the viewport. */
@media (max-width:760px){
  .tile-intro h2,
  .tile-intro>p{
    box-sizing:border-box!important;
    min-width:0!important;
    overflow-wrap:anywhere;
  }
  .tile-intro>p{
    width:calc(100% - 8px)!important;
    margin-left:2px!important;
  }
  .tech-stream{
    width:100%!important;
    min-width:0!important;
  }
  .tech-stream span{
    box-sizing:border-box!important;
    min-width:0!important;
    max-width:100%!important;
    white-space:normal!important;
    overflow-wrap:anywhere;
  }
  .tile-intro h2{
    font-size:clamp(36px,10.6vw,44px)!important;
    letter-spacing:-.06em!important;
  }
}

/* Social conversion, language flags and assistant form polish. */
.lang-switch a{display:inline-flex;align-items:center;gap:5px;padding:5px 8px}
.lang-switch a>span{font-size:13px;line-height:1;filter:saturate(.95);transform:translateY(-.5px)}
.lang-switch a[aria-current="page"]{background:rgba(255,255,255,.18);box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}
.footer-socials{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:9px;margin:4px 0}
.footer-links .footer-social{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:42px;padding:0 14px;border:1px solid rgba(255,255,255,.28);border-radius:999px;color:#fff;background:rgba(255,255,255,.07);box-shadow:inset 0 1px rgba(255,255,255,.1);transition:transform .18s ease,background .18s ease,border-color .18s ease}
.footer-links .footer-social:hover{transform:translateY(-2px);background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.48)}
.footer-links .footer-instagram{background:linear-gradient(120deg,rgba(131,58,180,.35),rgba(253,29,29,.25),rgba(252,176,69,.28))}
.footer-links .footer-whatsapp{background:rgba(37,195,106,.16);border-color:rgba(74,225,139,.34)}
.footer-social span{display:grid;width:20px;height:20px;place-items:center;border-radius:6px;background:rgba(255,255,255,.14);font-size:14px}
.assistant-social-proof{display:grid;grid-template-columns:1fr auto;gap:14px;align-items:center;margin:0 0 18px;padding:15px;border:1px solid #d6e3f5;border-radius:20px;background:linear-gradient(135deg,#eef5ff,#fff 58%,#effaf3);box-shadow:0 10px 25px rgba(10,42,79,.08)}
.assistant-social-kicker{display:block;margin-bottom:6px;color:#b06b19;font:800 8px/1 'DM Mono';letter-spacing:.1em}
.assistant-social-proof strong{display:block;color:#102842;font:800 14px/1.15 Manrope,Arial,sans-serif;letter-spacing:-.025em}
.assistant-social-proof p{margin:5px 0 0;color:#607088;font:500 10px/1.45 Manrope,Arial,sans-serif}
.assistant-social-actions{display:grid;gap:7px;min-width:142px}
.assistant-social-actions a{display:flex;align-items:center;justify-content:center;gap:6px;min-height:35px;padding:0 10px;border:1px solid #c8d9ed;border-radius:999px;color:#173452;background:#fff;text-decoration:none;font:800 9px/1 Manrope,Arial,sans-serif;transition:transform .18s ease,box-shadow .18s ease}
.assistant-social-actions a:first-child{border:0;background:linear-gradient(110deg,#6e3be8,#d6387b,#f49335);color:#fff;box-shadow:0 7px 16px rgba(164,52,117,.22)}
.assistant-social-actions a:last-child{border-color:#bde9cf;background:#eaf9f0;color:#176238}
.assistant-social-actions a:hover{transform:translateY(-1px);box-shadow:0 9px 18px rgba(12,42,76,.14)}
.chat-panel{background:linear-gradient(180deg,#fbfcff,#f7f8fb);border-color:#d8e3f0}
.assistant-stage{margin-bottom:14px;border-radius:24px;box-shadow:0 16px 32px rgba(8,23,42,.18)}
.lead-wizard{padding:17px;border:1px solid #dce5f1;border-radius:22px;background:#fff;box-shadow:0 12px 28px rgba(18,43,68,.07)}
.lead-step h3{font-size:clamp(22px,5vw,28px);margin-top:10px}
.step-copy{margin-bottom:18px;color:#6b7b91}
.project-form label>span,.choice-group legend{font-size:11px}
.project-form input:not([type=checkbox]),.project-form textarea,.project-form select{border-width:1.5px;background:#fbfcff;box-shadow:inset 0 1px 2px rgba(10,34,65,.03)}
.choice-grid label>span{border-width:1.5px;background:#fbfcff}
.wizard-next,.submit-project{background:linear-gradient(105deg,#0d2747,#174d7b);box-shadow:0 12px 24px rgba(13,39,71,.22)}
@media(max-width:760px){.lang-switch{gap:2px;margin-left:2px;padding-left:6px}.lang-switch a{gap:3px;padding:4px 5px;font-size:9px}.lang-switch a>span{font-size:11px}.footer-socials{justify-content:flex-start}.assistant-social-proof{grid-template-columns:1fr;padding:13px}.assistant-social-actions{grid-template-columns:1fr 1fr;min-width:0}.lead-wizard{padding:14px;border-radius:19px}}

/* Final assistant badge fix: keep the label visually attached to the robot. */
.assistant-launch .assistant-badge{
  right:2px;
  left:auto;
  bottom:174px;
  display:flex;
  align-items:center;
  gap:7px;
  max-width:none;
  padding:8px 12px;
  border:1px solid rgba(101,223,255,.42);
  border-radius:999px;
  background:linear-gradient(135deg,rgba(6,20,42,.97),rgba(13,48,83,.96));
  color:#fff;
  box-shadow:0 10px 24px rgba(2,12,28,.32),inset 0 1px rgba(255,255,255,.12);
  font-size:9px;
  line-height:1;
  white-space:nowrap;
  transform:none;
  opacity:1;
}
.assistant-launch .assistant-badge::after{
  content:'';
  position:absolute;
  right:30px;
  bottom:-5px;
  width:9px;
  height:9px;
  border-right:1px solid rgba(101,223,255,.42);
  border-bottom:1px solid rgba(101,223,255,.42);
  background:#0d3053;
  transform:rotate(45deg);
}
.assistant-launch:hover .assistant-badge,
.assistant-launch:focus-visible .assistant-badge{
  transform:translateY(-2px);
  box-shadow:0 13px 28px rgba(2,12,28,.38),inset 0 1px rgba(255,255,255,.14);
}
@media(min-width:1180px){
  .assistant-launch,.assistant-launch:hover{width:178px;min-height:184px}
  .assistant-launch .robot-img{width:168px;height:190px}
  .assistant-launch::before{width:128px;height:128px}
  .assistant-launch .assistant-badge{right:2px;left:auto;bottom:200px;font-size:10px;padding:9px 13px}
}
@media(max-width:760px){
  .assistant-launch .assistant-badge{right:1px;left:auto;bottom:140px;max-width:none;padding:7px 9px;font-size:8px}
}
@media(max-width:380px){
  .assistant-launch .assistant-badge{right:0;left:auto;bottom:130px;max-width:none;padding:6px 8px;font-size:7.5px}
}

/* Release guard: final rule wins every earlier collage/card override on phones. */
@media(max-width:760px){
  .world.tile-experience,
  .world.tile-experience *{box-sizing:border-box}
  .tile-copy,.tile-intro,.tech-stream{width:100%!important;max-width:100%!important;min-width:0!important}
  .tile-intro h2{width:calc(100% - 8px)!important;max-width:calc(100% - 8px)!important;margin-left:2px!important;font-size:clamp(36px,10.6vw,44px)!important;letter-spacing:-.06em!important;overflow-wrap:anywhere}
  .tile-intro>p{width:calc(100% - 12px)!important;max-width:calc(100% - 12px)!important;margin-left:3px!important;overflow-wrap:anywhere}
  .tech-stream span{width:100%!important;min-width:0!important;max-width:100%!important;white-space:normal!important;overflow-wrap:anywhere}
}

/* Release icons: placed last so legacy emoji sizing cannot override them. */
.lang-switch .flag-icon{position:relative;display:inline-block;flex:0 0 auto;width:18px!important;height:12px!important;border-radius:2px;overflow:hidden;border:1px solid rgba(255,255,255,.58);box-shadow:0 1px 3px rgba(2,15,35,.28);transform:none!important;filter:none!important}
.flag-pt{background:linear-gradient(90deg,#066b3a 0 40%,#db2535 40%)}.flag-pt::after{content:"";position:absolute;left:6px;top:3px;width:4px;height:4px;border:1px solid #ffd34e;border-radius:50%}
.flag-es{background:linear-gradient(#aa151b 0 25%,#f1bf00 25% 75%,#aa151b 75%)}
.flag-gb{background:linear-gradient(32deg,transparent 43%,#fff 43% 50%,#c8102e 50% 56%,#fff 56% 63%,transparent 63%),linear-gradient(-32deg,transparent 43%,#fff 43% 50%,#c8102e 50% 56%,#fff 56% 63%,transparent 63%),linear-gradient(90deg,transparent 40%,#fff 40% 45%,#c8102e 45% 55%,#fff 55% 60%,transparent 60%),linear-gradient(transparent 34%,#fff 34% 40%,#c8102e 40% 60%,#fff 60% 66%,transparent 66%),#012169}
.flag-br{background:#149447}.flag-br::before{content:"";position:absolute;left:4px;top:2px;width:8px;height:8px;background:#ffdf00;transform:rotate(45deg)}.flag-br::after{content:"";position:absolute;left:7px;top:4px;width:5px;height:5px;border-radius:50%;background:#002776}
.footer-links .footer-email,.footer-links button[data-open-privacy]{display:inline-flex;align-items:center;gap:9px}
.footer-links .footer-email::before,.footer-links button[data-open-privacy]::before{content:"";width:18px;height:18px;flex:0 0 auto;background:center/contain no-repeat}
.footer-links .footer-email::before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238fdcff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='14' rx='4'/%3E%3Cpath d='m5 8 7 5 7-5'/%3E%3C/svg%3E")}
.footer-links button[data-open-privacy]::before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238fdcff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='5' y='10' width='14' height='10' rx='3'/%3E%3Cpath d='M8 10V7a4 4 0 0 1 8 0v3M12 14v2'/%3E%3C/svg%3E")}
.footer-social span{display:grid;width:24px!important;height:24px!important;place-items:center;border-radius:8px}.footer-social span svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}.footer-social span svg .icon-fill{fill:currentColor;stroke:none}
@media(max-width:760px){.lang-switch .flag-icon{width:16px!important;height:11px!important}.lang-switch a{gap:4px!important}.footer-social span{width:22px!important;height:22px!important}}

/* === azulejo-ascii.css === */
/* The azulejo wall "transforms" into a diagonal-hatch ASCII rendition while the
   visitor scrolls through the section, echoing the hero's own day/night cycle
   but scroll-scrubbed instead of always-on (the section itself has no
   day/night state to hook into — direct request: "como no hero que fica a
   noite, o azulejo transforma em ascii"). Rendered as a raster WEBP, not
   inline SVG like the medallion/skyline: a per-cell diagonal-line hatch at
   this density is ~6000 <line> elements, 700KB+ as SVG text — a busy photo
   texture like this compresses far better as WEBP (175KB) than as verbose
   XML, so this one file breaks the project's inline-SVG-first convention on
   purpose. cinema.js's wireAzulejoAscii() drives --azulejo-ascii-o via a
   scroll-scrub tied to the section itself; opacity 0 at both ends (real
   photo shows) and peaking mid-scroll (ascii shows), same tri() envelope
   shape as the rest of the file's scroll-driven effects. */
.azulejo-ascii{
  position:absolute;
  inset:0;
  z-index:0;
  pointer-events:none;
  background-image:url('azulejo-ascii-diagonal.webp');
  background-position:center;
  background-size:420px auto;
  background-repeat:repeat;
  opacity:var(--azulejo-ascii-o,0);
}
@media(prefers-reduced-motion:reduce){.azulejo-ascii{display:none!important}}

/* === ascii-showcase.css === */
/* 2026-08-27, second pass: replaced the full-bleed sky-photo + toggle version
   outright per direct request ("background, porta retrato de madeira vintage
   ... before e after ascii igual ao ascii-magic.com capa principal"). Now:
   a dark ambient scene (.ascii-frame-scene, matches the near-black background
   ascii-magic.com's own homepage hero uses) holding a vintage wooden picture
   frame (.ascii-frame, built from layered CSS gradients — no raster wood
   texture asset) around a cream mat (.ascii-frame-mat) and a drag-to-reveal
   before/after (.ascii-compare) — same left-clips-before/right-reveals-after
   clip-path direction already fixed once this session (clip-path:inset(0 0 0
   var(--reveal)) on the AFTER layer, not the before one). "Before" is the
   hand-painted illustration (lisboncitysunset.png, user-supplied); "After" is
   ascii-animation.mp4, a pre-rendered looping ascii/glitch treatment of the
   same illustration (also user-supplied, transcoded 7MB->~120KB for web:
   scaled to 700w, crf 30, audio stripped). Drag/keyboard logic lives in
   bundle.js's ascii-compare.js section. */
.ascii-showcase{
  position:relative;
  overflow:hidden;
  background:#050a14;
  color:#f6f2e9;
}
.ascii-frame-scene{
  position:absolute;
  inset:0;
  z-index:0;
  overflow:hidden;
  background:url('restaurant-ambience-poster.webp') center/cover no-repeat;
}
.ascii-frame-scene::after{
  content:'';
  position:absolute;
  inset:0;
  z-index:2;
  pointer-events:none;
  background:
    radial-gradient(ellipse 75% 55% at 50% 18%,rgba(8,7,14,.48),transparent 68%),
    linear-gradient(180deg,rgba(8,7,14,.28) 0%,rgba(8,7,14,.58) 68%,rgba(8,7,14,.82) 100%);
}
.ascii-bg-video{
  position:absolute;
  inset:0;
  z-index:1;
  width:100%;
  height:100%;
  object-fit:cover;
}
@media(prefers-reduced-motion:reduce){
  .ascii-bg-video{display:none}
}
.ascii-shelf-scene{
  display:flex;
  flex-direction:column;
  align-items:center;
  margin:44px auto 0;
  max-width:94vw;
}
.ascii-shelf-scene .ascii-frame{margin:0}
.ascii-shelf{
  width:100%;
  height:30px;
  margin-top:-2px;
  border-radius:0 0 3px 3px;
  background:
    repeating-linear-gradient(90deg,rgba(0,0,0,.12) 0 2px,transparent 2px 8px),
    linear-gradient(180deg,#9a6a3e 0%,#7a4d2c 45%,#5c3820 100%);
  box-shadow:
    0 20px 34px rgba(0,0,0,.55),
    inset 0 2px 0 rgba(255,255,255,.2),
    inset 0 -8px 12px rgba(0,0,0,.4);
}
.ascii-showcase-inner{
  position:relative;
  z-index:1;
  padding:100px max(24px,calc((100% - 1180px)/2)) 110px;
  text-align:center;
  display:flex;
  flex-direction:column;
  align-items:center;
}
.ascii-showcase .section-index{color:#8fdcff}
.ascii-showcase h2{
  font-size:clamp(38px,4.3vw,61px);
  line-height:1;
  letter-spacing:-.065em;
  margin:10px 0 0;
  color:#fff;
}
.ascii-showcase h2 em{
  font-family:'Playfair Display',serif;
  font-weight:600;
  font-style:italic;
  letter-spacing:-.075em;
  color:#f6a35c;
}
.ascii-showcase-copy{
  max-width:52ch;
  margin:16px 0 0;
  color:rgba(246,242,233,.78);
  font-size:15px;
}
.ascii-frame{
  margin:44px auto 0;
  padding:22px;
  width:min(420px,80vw);
  border-radius:8px;
  background:
    repeating-linear-gradient(90deg,rgba(0,0,0,.14) 0 2px,transparent 2px 7px),
    linear-gradient(135deg,#8a5a34 0%,#6b4226 35%,#7a4d2c 55%,#4a2c17 80%,#6b4226 100%);
  box-shadow:
    0 32px 70px rgba(0,0,0,.5),
    inset 0 0 0 2px rgba(0,0,0,.3),
    inset 0 2px 3px rgba(255,255,255,.15),
    inset 0 -3px 6px rgba(0,0,0,.35);
}
.ascii-frame-mat{
  padding:16px;
  background:#efe6d8;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.1),inset 0 6px 16px rgba(0,0,0,.18);
}
.ascii-compare{
  position:relative;
  overflow:hidden;
  width:100%;
  aspect-ratio:700/1052;
  background:#05080e;
  /* pan-y (not none): this is a tall full-width element on mobile — with
     touch-action:none a finger landing anywhere on it froze the whole page
     scroll. pan-y lets vertical swipes scroll natively; the compare drag in
     bundle.js only claims the gesture once it reads as horizontal. */
  touch-action:pan-y;
  cursor:ew-resize;
}
.ascii-compare-before,
.ascii-compare-after,
.ascii-compare-video{
  position:absolute;
  inset:0;
  display:block;
  width:100%;
  height:100%;
  object-fit:cover;
}
.ascii-compare-after{clip-path:inset(0 0 0 var(--reveal,50%))}
.ascii-compare-labels{
  position:absolute;
  inset:14px 14px auto;
  display:flex;
  justify-content:space-between;
  pointer-events:none;
  z-index:2;
}
.ascii-compare-labels span{
  padding:4px 10px;
  border-radius:999px;
  background:rgba(5,8,14,.55);
  color:#f6f2e9;
  font-size:11px;
  font-weight:700;
  letter-spacing:.06em;
  text-transform:uppercase;
  transition:opacity .15s linear;
}
.ascii-compare-handle{
  position:absolute;
  top:50%;
  left:var(--reveal,50%);
  transform:translate(-50%,-50%);
  /* deliberate 36px grab target — a drag starting here is always the slider,
     never a scroll, so it opts out of the parent's pan-y */
  touch-action:none;
  width:36px;
  height:36px;
  border-radius:50%;
  border:2px solid rgba(255,255,255,.8);
  background:rgba(5,8,14,.65);
  color:#fff;
  font-size:13px;
  line-height:1;
  cursor:ew-resize;
  z-index:3;
}
.ascii-compare-handle:focus-visible{outline:2px solid #8fdcff;outline-offset:3px}
@media(max-width:760px){
  .ascii-showcase-inner{padding:72px var(--mobile-gutter) 84px}
  .ascii-frame{width:88vw}
}

/* === topbar-narrow-fix.css === */
/* At narrow phone widths (~360-375px) the topbar's brand + nav content was
   wider than the available space, so justify-content:space-between had zero
   room left to distribute — "Contacto" ended up glued directly against
   "WEBFOLIO" with no visible gap. Tightens nav/lang-switch sizing further
   (beyond the general 760px pass above) so the two sides keep a real gap
   down to ~360px; narrower still degrades gracefully rather than breaking. */
@media(max-width:760px){
  .topbar nav{gap:6px}
  .topbar nav>a{font-size:10px!important}
  .lang-switch{gap:1px!important;margin-left:0!important;padding-left:4px!important}
  .lang-switch a{gap:2px!important;padding:3px 4px!important}
  .lang-switch .flag-icon{width:13px!important;height:9px!important}
}

/* === ascii-showcase-desktop-layout.css === */
/* 2026-08-30: on full-width desktop the ascii-showcase rendered as a small
   420px portrait frame stranded in the centre of a near-black full-viewport
   section — enormous dead space either side ("versao desktop tela cheia
   portfolio", reported with screenshot). The section content already exists
   (kicker, h2, bespoke line, copy, framed before/after) — it was just all
   stacked and centre-aligned. From 1000px up this switches .ascii-showcase-inner
   to a two-column editorial grid: text block left-aligned in column 1, the
   vintage frame + shelf enlarged in column 2, vertically centred against the
   text. CSS-only (no markup change, so tools/build_locales.py output is
   untouched) — grid item placement keys off the existing child classes.
   Below 1000px the original single-column centred layout is unchanged. */
@media(min-width:1000px){
  .ascii-showcase-inner{
    /* .wrap caps this element at width:min(1180px,100% - 72px). The earlier
       attempt to widen the section via huge horizontal padding backfired:
       padding on a fixed-width border-box shrinks the content area instead
       of growing it, so on wide/ultrawide monitors column 1 collapsed and
       the h2 overflowed behind the frame ("sessao 03 zuado em todas
       resolucoes", 2026-08-30). Fix: override the width cap itself and keep
       the gutter modest, so the two columns always have real room. */
    width:min(1440px,calc(100% - 96px));
    margin-inline:auto;
    padding-left:clamp(24px,4vw,56px);
    padding-right:clamp(24px,4vw,56px);
    display:grid;
    grid-template-columns:minmax(0,1fr) auto;
    grid-template-rows:auto auto auto auto;
    column-gap:clamp(40px,5vw,90px);
    align-items:start;
    justify-items:start;
    text-align:left;
  }
  .ascii-showcase-inner>.section-index{grid-column:1;grid-row:1}
  .ascii-showcase-inner>h2{grid-column:1;grid-row:2;max-width:none;font-size:clamp(34px,3vw,52px)}
  .ascii-showcase-inner>.bespoke-line{grid-column:1;grid-row:3}
  .ascii-showcase-inner>.ascii-showcase-copy{grid-column:1;grid-row:4;max-width:42ch}
  .ascii-showcase-inner>.ascii-shelf-scene{
    grid-column:2;
    grid-row:1 / 5;
    align-self:center;
    margin:0;
    max-width:none;
  }
  .ascii-showcase-inner .ascii-frame{
    width:clamp(320px,26vw,430px);
    margin:0;
  }
}

/* === audit-polish.css === */
/* 2026-08-31 — implements the mobile visual audit (artifact "Crítica Visual
   RE WEBFOLIO"). Appended last so it wins on source order; `!important` only
   where an earlier section already forces the same property. Grouped by the
   audit's numbered points. User-approved direction: mascote → discreet FAB;
   "O Estúdio" chips → sober outline; project museum labels → removed. */

/* --- pt.6 — H1 tracking collapses words on mobile ("Ideiasdigitais") ------- */
@media (max-width:760px){
  .hero h1{
    letter-spacing:-.028em !important;
    line-height:1.02 !important;
    overflow-wrap:normal;
    word-break:keep-all;
    hyphens:none;
    font-size:clamp(40px,10.8vw,52px) !important;
  }
  .selected-work h2,
  .ascii-showcase h2,
  .tile-intro h2,
  .capabilities h2{ letter-spacing:-.02em; }
  .tile-intro h2{ word-spacing:.02em; }
}

/* --- pt.5 — body copy legibility over image / video ----------------------- */
@media (max-width:760px){
  .city-vignette{
    background:
      linear-gradient(90deg,rgba(3,13,28,.9) 0%,rgba(3,13,28,.62) 32%,rgba(3,13,28,.3) 70%,rgba(3,13,28,.52) 100%),
      linear-gradient(0deg,rgba(3,13,28,.74),transparent 44%) !important;
  }
  .hero-lede{ text-shadow:0 1px 14px rgba(3,13,28,.8),0 0 3px rgba(3,13,28,.6); }
  .ascii-showcase-copy{
    background:rgba(6,12,22,.56);
    border-radius:12px;
    padding:13px 15px;
    -webkit-backdrop-filter:blur(3px);
    backdrop-filter:blur(3px);
    text-shadow:0 1px 8px rgba(0,0,0,.5);
  }
}

/* --- pt.16 — the "✦ + mono in a ghost pill" component (hero + ascii) ------ */
.bespoke-line{
  display:block !important;
  max-width:44ch !important;
  margin:0 0 22px !important;
  padding:0 0 0 14px !important;
  border:0 !important;
  border-left:2px solid #f4c952 !important;
  border-radius:0 !important;
  background:none !important;
  -webkit-backdrop-filter:none !important;
  backdrop-filter:none !important;
  color:rgba(255,255,255,.94) !important;
  font:500 13px/1.6 Manrope,Arial,sans-serif !important;
  letter-spacing:0 !important;
}
.bespoke-line::before{ display:none !important; }
@media (max-width:760px){ .bespoke-line{ font-size:12.5px !important; } }

/* --- pt.13 — calm the "sticker" eyebrow + the tilted note card ------------ */
.tile-experience .section-index{
  display:block !important;
  width:auto !important;
  padding:0 !important;
  border:0 !important;
  border-radius:0 !important;
  background:none !important;
  box-shadow:none !important;
  color:#0a2f6b !important;
  font:600 11px/1 "DM Mono",ui-monospace,monospace !important;
  letter-spacing:.15em;
  text-transform:uppercase;
}
.made-to-measure{
  transform:none !important;
  box-shadow:0 10px 28px rgba(6,43,99,.18) !important;
  border-left:3px solid #d72f42 !important;
  border-radius:3px;
}
/* the two "O Estúdio" cards: keep the plaque + terracotta identity, drop the
   hard offset shadow + tilt that made everything read as stickers */
.tile-intro h2{
  transform:none !important;
  box-shadow:0 8px 24px rgba(6,43,99,.16) !important;
  border-radius:6px;
}
.tile-intro>p{
  transform:none !important;
  background:#bf492e !important;
  box-shadow:0 10px 28px rgba(120,32,10,.2) !important;
  border-radius:6px;
}

/* --- pt.4 — "O Estúdio": mute the azulejo behind the text (readability scrim) */
.world.tile-experience{ isolation:isolate; }
.world.tile-experience::after{
  content:"" !important;
  display:block !important;
  position:absolute !important;
  inset:0 !important;
  z-index:0 !important;
  pointer-events:none !important;
  background:rgba(244,246,250,.76) !important;
  mix-blend-mode:normal !important;
}
.world.tile-experience .tile-copy{ position:relative; z-index:1; }

/* --- pt.2 / pt.12 — sober outline chips, one pill language ---------------- */
.world.tile-experience .tech-stream{
  display:flex !important;
  flex-wrap:wrap;
  justify-content:flex-start;
  gap:8px !important;
  grid-template-columns:none !important;
  max-width:none !important;
}
.world.tile-experience .tech-stream span{
  all:unset;
  box-sizing:border-box;
  display:inline-flex !important;
  align-items:center;
  justify-content:center;
  height:auto !important;
  min-width:0 !important;
  width:auto !important;
  padding:.52em .9em !important;
  border:1px solid rgba(10,47,107,.3) !important;
  border-radius:999px !important;
  background:rgba(255,255,255,.5) !important;
  color:#0a2f6b !important;
  font:600 12px/1 Manrope,Arial,sans-serif !important;
  letter-spacing:.01em !important;
  white-space:nowrap !important;
  box-shadow:none !important;
  transform:none !important;
  transition:background .18s ease,border-color .18s ease;
}
.world.tile-experience .tech-stream span:hover{
  background:#0a3b81 !important;
  border-color:#0a3b81 !important;
  color:#fff !important;
}
@media (max-width:760px){
  .world.tile-experience .tech-stream span{ font-size:11px !important; white-space:normal !important; }
}

/* --- pt.8 — lighten the gallery frame on mobile ------------------------- */
@media (max-width:760px){
  .work-cover{
    padding:6px !important;
    border-radius:4px !important;
    box-shadow:
      0 0 0 1px rgba(58,38,12,.4),
      0 14px 26px rgba(20,10,4,.22) !important;
  }
  .gallery-varnish{ opacity:.5 !important; }
}

/* --- pt.9 — the two worst rhythm breaks (card gap, ascii→footer void) --- */
.work-card--featured{ margin-bottom:0 !important; }
.work-card--featured + .work-card--featured{ margin-top:clamp(40px,9vw,64px) !important; }
@media (max-width:760px){
  .ascii-showcase{ padding-bottom:0 !important; }
  .ascii-showcase-inner{ padding-bottom:40px !important; }
  .ascii-shelf-scene{ margin-bottom:0 !important; }
  .selected-work{ padding-bottom:56px !important; }
}

/* --- pt.11 — header: restore "O estúdio" on mobile, compact the language switch --- */
@media (max-width:760px){
  .topbar nav{ gap:9px !important; flex-wrap:nowrap; }
  .topbar nav>a{ font-size:11px !important; white-space:nowrap; }
  .topbar nav>a:first-child{ display:inline-block !important; }
  .lang-switch{ gap:0 !important; margin-left:2px !important; }
  .lang-switch a{ padding:3px 4px !important; font-size:10px !important; gap:0 !important; }
  .lang-switch .flag-icon{ display:none !important; }
  .brand span{ letter-spacing:.1em; }
}

/* --- pt.1 / pt.3 — mascote: one discreet round launcher at every width,
   the 3D-robot + "postcard" URL render dropped (it fought the site's
   hand-painted / azulejo world and read as a template chatbot). The
   assistant itself is untouched — only its launcher. --------------------- */
.quick-actions .assistant-launch,
.quick-actions .assistant-launch:hover{
  width:60px !important;
  min-height:60px !important;
  height:60px;
  padding:0 !important;
  border-radius:50% !important;
  background:linear-gradient(150deg,#0c2848,#123a5f) !important;
  box-shadow:0 12px 26px rgba(4,12,26,.4) !important;
  overflow:visible;
  display:grid;
  place-items:center;
  transform:none !important;
}
.quick-actions .assistant-launch:hover{ transform:translateY(-2px) !important; }
.quick-actions .assistant-launch>span:first-child{
  display:grid !important;
  place-items:center;
  width:auto !important;
  height:auto !important;
  padding:0 !important;
  border:0 !important;
  box-shadow:none !important;
  background:none !important;
  color:#eaf3ff !important;
  font:800 16px/1 "DM Mono",ui-monospace,monospace !important;
  letter-spacing:.06em;
}
.quick-actions .assistant-launch .robot-img,
.quick-actions .assistant-launch::before{ display:none !important; }
/* keep the name as a hover/focus tooltip on desktop; hidden by default,
   never on load */
.quick-actions .assistant-launch .assistant-badge{
  left:auto !important;
  right:calc(100% + 10px) !important;
  bottom:50% !important;
  transform:translateY(50%) !important;
  opacity:0 !important;
  visibility:hidden !important;
  transition:opacity .18s ease,visibility .18s ease;
}
.quick-actions .assistant-launch:hover .assistant-badge,
.quick-actions .assistant-launch:focus-visible .assistant-badge{
  opacity:1 !important;
  visibility:visible !important;
}
@media (max-width:760px){
  .quick-actions .assistant-launch,
  .quick-actions .assistant-launch:hover{ width:54px !important; min-height:54px !important; height:54px; }
  .quick-actions .assistant-launch>span:first-child{ font-size:15px !important; }
  .quick-actions .assistant-launch .assistant-badge{ display:none !important; }
}

/* === azulejo-color-restore.css === */
/* pt.4's readability scrim was a flat rgba(244,246,250,.76) full-bleed wash —
   it muted the whole azulejo wall to near-white ("meio sem cores"). Replace
   it with a warm-cream GRADIENT scrim: opaque where the eyebrow/heading sit,
   clearing toward the open edge so the tile pattern keeps its cobalt colour.
   The plaque <h2>, terracotta <p> and (mobile) navy note card all carry their
   own solid backgrounds, so they stay legible without a heavy global veil. */
.world.tile-experience::after{
  background:linear-gradient(
    118deg,
    rgba(245,242,235,.9) 0%,
    rgba(245,242,235,.72) 30%,
    rgba(245,242,235,.34) 58%,
    rgba(245,242,235,.08) 80%,
    rgba(245,242,235,0) 100%
  ) !important;
  mix-blend-mode:normal !important;
}
@media (max-width:760px){
  /* stacked layout: fade top-to-bottom instead, cover the eyebrow up top */
  .world.tile-experience::after{
    background:linear-gradient(
      180deg,
      rgba(245,242,235,.92) 0%,
      rgba(245,242,235,.66) 26%,
      rgba(245,242,235,.3) 55%,
      rgba(245,242,235,.06) 82%,
      rgba(245,242,235,0) 100%
    ) !important;
  }
}

/* With the scrim lighter, the pt.2/pt.12 outline chips (rgba white .5 fill,
   .3 border) read as washed-out "apagados" over the now-visible cobalt tiles.
   Keep the sober outline-pill language, just make them fully opaque with a
   crisp border + soft lift so they sit ON the wall, not behind it. */
.world.tile-experience .tech-stream span{
  background:#0a2f6b !important;
  border:1px solid #0a2f6b !important;
  color:#fff !important;
  font-weight:600 !important;
  letter-spacing:.02em !important;
  box-shadow:0 3px 12px rgba(6,28,58,.28) !important;
}
.world.tile-experience .tech-stream span:hover{
  background:#c2410c !important;
  border-color:#c2410c !important;
  color:#fff !important;
  box-shadow:0 5px 16px rgba(120,40,10,.34) !important;
}
/* the "Conhecimento que liga…" strip: ensure it stays a solid, high-contrast
   plate on the wall (it was already navy, but pin it against future overrides) */
.world.tile-experience .made-to-measure{
  background:#082d67 !important;
  color:#fff !important;
  box-shadow:0 8px 24px rgba(6,28,58,.26) !important;
}

/* === ementa-demo.css === */
/* Section 03 rework (2026-09-02): the ANTES/ASCII wooden-frame drag compare is
   replaced by a live "Ementa Digital" demo — a device frame running one of two
   art-directed Portuguese menus (Taberna / Esplanada) with a real scannable QR.
   The waves background (.ascii-frame-scene / .ascii-bg-video) is deliberately
   KEPT. The old .ascii-frame / .ascii-compare / .ascii-shelf rules above are now
   dead (their markup is gone) but left in place per the project's archive-don't-
   delete convention; ascii-compare.js in bundle.js already no-ops when the
   elements are absent. See BRIEF_EMENTA_DIGITAL_2026-09-02.md.
   Progressive enhancement: both menus are real text in the HTML; ementa-demo.js
   only adds the template switch, in-frame scrollspy and dish-note expand. */

.ascii-showcase .ascii-showcase-copy{ max-width:56ch; }

/* Restaurant theme (2026-09-02): the section background video is now warm
   fine-dining ambience footage (restaurant-ambience.*, Mixkit free licence)
   instead of the retired sunset waves. Shift the section accent from the old
   sky-blue (#e6b170) to a warm brass that sits with the footage and the
   Taberna menu. */
.ascii-frame-scene{
  background:url('restaurant-ambience-poster.webp') center/cover no-repeat !important;
}
/* video treatment: neutral grade + a very slow ken-burns push so a short
   loop reads as a live room, not a repeating clip. The source is a sharp
   1080p plated-food shot downscaled to 720 (sharper than native 720). */
.ascii-bg-video{
  filter:saturate(1.06) contrast(1.05) brightness(.84) !important;
  transform:scale(1.07);
  transform-origin:58% 42%;
  animation:asciiRoomDrift 46s ease-in-out infinite alternate;
  will-change:transform;
}
@keyframes asciiRoomDrift{
  from{ transform:scale(1.06) translate3d(-1.2%,0.6%,0); }
  to{   transform:scale(1.12) translate3d(1.4%,-1%,0); }
}
/* ::before — brand-tint + film grain, so the stock clip reads as one
   material with the rest of the section instead of a raw drop-in */
.ascii-frame-scene::before{
  content:"";
  position:absolute;
  inset:0;
  z-index:2;
  pointer-events:none;
  background:
    linear-gradient(180deg,rgba(26,21,18,.34),rgba(20,14,10,.5) 60%,rgba(14,10,7,.78)),
    radial-gradient(120% 90% at 50% 8%,rgba(196,150,90,.12),transparent 55%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
  background-size:auto,auto,140px 140px;
  mix-blend-mode:multiply;
}
.ascii-frame-scene::after{
  z-index:3 !important;
  background:
    radial-gradient(ellipse 70% 58% at 50% 40%,transparent 0 34%,rgba(8,6,3,.42) 100%),
    linear-gradient(180deg,rgba(12,9,6,.4) 0%,rgba(9,7,4,.3) 34%,rgba(9,7,4,.5) 74%,rgba(8,6,3,.82) 100%) !important;
}
@media (prefers-reduced-motion:reduce){
  .ascii-bg-video{ animation:none; transform:scale(1.06); }
}
.ascii-showcase .section-index{ color:#e6b170 !important; }
.ascii-showcase h2 em{ color:#e9b878; }
.ascii-showcase h2,
.ascii-showcase .bespoke-line,
.ascii-showcase .ascii-showcase-copy{
  text-shadow:0 1px 12px rgba(0,0,0,.45);
}

/* The 2026-08-30 "ascii-showcase-desktop-layout.css" marker turns
   .ascii-showcase-inner into a 2-col grid and places children by class
   (text in col 1, the old frame in col 2). The ementa demo is a different
   composition — a centred text block above a self-contained device+QR stage —
   so on desktop we revert to a single centred column and let .ementa-stage
   own its own columns. This section loads after that marker, so it wins. */
@media (min-width:1000px){
  .ascii-showcase-inner{
    display:flex;
    flex-direction:column;
    align-items:center;
    text-align:center;
    width:min(1180px,calc(100% - 72px));
    padding-left:0;
    padding-right:0;
    grid-template-columns:none;
    grid-template-rows:none;
  }
  .ascii-showcase-inner > .section-index,
  .ascii-showcase-inner > h2,
  .ascii-showcase-inner > .bespoke-line,
  .ascii-showcase-inner > .ascii-showcase-copy,
  .ascii-showcase-inner > .ementa-demo{
    grid-column:auto;
    grid-row:auto;
  }
  .ascii-showcase-inner > h2{
    max-width:26ch;
    font-size:clamp(28px,2.9vw,41px);
    line-height:1.1;
    text-align:center;
  }
  .ascii-showcase-inner > .ascii-showcase-copy{ margin-left:auto; margin-right:auto; }
}
.ascii-showcase h2 em{ font-size:1em; }

/* the shared .bespoke-line (yellow left-rule lead) reads oddly centred in this
   section — make it a plain centred statement here */
.ascii-showcase .bespoke-line{
  border:0 !important;
  padding:0 !important;
  margin:14px auto 0 !important;
  max-width:44ch;
  font-size:14px !important;
  font-weight:600;
  color:#f6f2e9 !important;
  text-align:center;
}
.ascii-showcase .bespoke-line::before{ display:none !important; }

.ementa-demo{
  width:100%;
  margin:40px auto 0;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:22px;
}

/* --- template switcher (segmented control, tab semantics) ---------------- */
.ementa-switch{
  display:inline-flex;
  padding:5px;
  border-radius:999px;
  background:rgba(8,12,22,.55);
  border:1px solid rgba(246,242,233,.16);
  backdrop-filter:blur(4px);
}
.ementa-switch-btn{
  appearance:none;
  border:0;
  cursor:pointer;
  padding:9px 18px;
  border-radius:999px;
  background:transparent;
  color:rgba(246,242,233,.7);
  font:600 13px/1 Manrope,Arial,sans-serif;
  letter-spacing:.01em;
  transition:background .18s ease,color .18s ease;
}
.ementa-switch-btn span{ opacity:.62; font-weight:500; }
.ementa-switch-btn[aria-selected="true"]{
  background:#f6f2e9;
  color:#12130f;
}
.ementa-switch-btn[aria-selected="true"] span{ opacity:.7; }
.ementa-switch-btn:focus-visible{ outline:2px solid #e6b170; outline-offset:2px; }

/* --- stage: device + side panel ---------------------------------------- */
.ementa-stage{
  width:100%;
  display:grid;
  grid-template-columns:minmax(0,340px) minmax(0,240px);
  gap:38px;
  justify-content:center;
  align-items:start;
}

.ementa-device{
  position:relative;
  padding:14px;
  border-radius:38px;
  background:linear-gradient(155deg,#20222b,#0c0d12 60%,#181a22);
  box-shadow:
    0 40px 80px rgba(0,0,0,.55),
    inset 0 0 0 2px rgba(255,255,255,.06),
    inset 0 2px 4px rgba(255,255,255,.12);
}
.ementa-device-notch{
  position:absolute;
  top:20px;
  left:50%;
  transform:translateX(-50%);
  width:96px;
  height:18px;
  border-radius:0 0 14px 14px;
  background:#0c0d12;
  z-index:3;
}
.ementa-view{
  position:relative;
  border-radius:26px;
  overflow:hidden;
  isolation:isolate;
}
.ementa-menu{
  max-height:540px;
  overflow-y:auto;
  overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;
  padding:34px 24px 26px;
  font-family:Manrope,Arial,sans-serif;
}
.ementa-menu:focus-visible{ outline:2px solid #e6b170; outline-offset:-4px; }
.ementa-menu[hidden]{ display:none; }
.ementa-menu::-webkit-scrollbar{ width:6px; }
.ementa-menu::-webkit-scrollbar-thumb{ border-radius:3px; background:rgba(128,128,128,.4); }

.ementa-head{ text-align:center; }
.ementa-kicker{
  margin:0;
  font:600 10px/1 "DM Mono",ui-monospace,monospace;
  letter-spacing:.22em;
  text-transform:uppercase;
}
.ementa-casa{
  margin:10px 0 2px;
  font-size:clamp(22px,4.6vw,28px);
  line-height:1.05;
}
.ementa-loc{
  margin:0;
  font-size:11px;
  letter-spacing:.06em;
  text-transform:uppercase;
  opacity:.66;
}

.ementa-rail{
  position:sticky;
  top:0;
  z-index:2;
  display:flex;
  gap:6px;
  flex-wrap:wrap;
  justify-content:center;
  margin:18px -24px 6px;
  padding:10px 24px;
}
.ementa-rail a{
  text-decoration:none;
  font:600 11px/1 Manrope,Arial,sans-serif;
  letter-spacing:.02em;
  padding:6px 10px;
  border-radius:999px;
  white-space:nowrap;
  transition:background .16s ease,color .16s ease,border-color .16s ease;
}

.ementa-group{ margin-top:20px; }
.ementa-group h4{
  margin:0 0 10px;
  font-size:13px;
  letter-spacing:.16em;
  text-transform:uppercase;
}
.ementa-group ul{ list-style:none; margin:0; padding:0; }

.ementa-item{ padding:9px 0; }
.ementa-item + .ementa-item{ border-top:1px solid; border-color:inherit; }
.ei-row{
  display:flex;
  align-items:baseline;
  gap:8px;
}
.ei-name{ flex:1 1 auto; font-size:13.5px; line-height:1.4; }
.ei-tag{
  font-size:10px;
  letter-spacing:.08em;
  text-transform:uppercase;
  opacity:.6;
  white-space:nowrap;
}
.ei-dots{
  flex:1 1 auto;
  align-self:flex-end;
  transform:translateY(-3px);
  border-bottom:1px dotted currentColor;
  opacity:.4;
  min-width:14px;
}
.ei-price{ flex:0 0 auto; font-variant-numeric:tabular-nums; font-weight:600; font-size:13px; }
.ei-note{
  margin:5px 0 0;
  font-size:11.5px;
  line-height:1.45;
  opacity:0;
  max-height:0;
  overflow:hidden;
  transition:opacity .2s ease,max-height .2s ease,margin .2s ease;
}
.ementa-item.has-note{ cursor:pointer; position:relative; }
.ementa-item.has-note::after{
  content:"+";
  position:absolute;
  top:11px;
  right:0;
  font-size:11px;
  line-height:1;
  opacity:.4;
}
.ementa-item.has-note .ei-price{ margin-right:14px; }
.ementa-item.has-note.is-open::after{ content:"\2212"; }
.ementa-item.has-note.is-open .ei-note{
  opacity:.78;
  max-height:80px;
  margin-top:6px;
}

.ementa-item.is-out{ opacity:.42; }
.ementa-item.is-out .ei-price{ text-decoration:line-through; }
.ei-stamp{
  display:inline-block;
  margin-left:8px;
  padding:1px 7px;
  border:1px solid currentColor;
  border-radius:4px;
  font:700 9px/1.4 "DM Mono",ui-monospace,monospace;
  letter-spacing:.1em;
  text-transform:uppercase;
  transform:rotate(-3deg);
}

.ementa-fine{
  margin:22px 0 0;
  font-size:10px;
  line-height:1.5;
  letter-spacing:.03em;
  opacity:.6;
  text-align:center;
}

/* ---- Refined menu system: clean, light, fine-dining ------------------ */
/* Requested 2026-09-02: "requintado e luxoso, fundo branco/cinza, tons
   claros, fontes alinhadas com a restauração". Both templates now share one
   editorial system — serif display for the name and prices, hairline rules,
   letter-spaced caps for section labels, generous whitespace — and differ
   only in ground tone + accent: warm ivory (dinner) vs cool stone (bar). */
.ementa-menu{ padding:42px 30px 34px; text-align:left; }
.ementa-head{ text-align:center; }
.ementa-rail{ justify-content:center; }
.ementa-group h4,
.ementa-fine{ text-align:center; }
.ei-dots{ opacity:.3; min-width:22px; }
.ementa-casa{
  font-family:"Playfair Display",Georgia,serif;
  font-weight:600;
  letter-spacing:.004em;
  font-size:clamp(23px,4.6vw,29px);
}
.ementa-kicker{ font-weight:500; opacity:.72; }
.ementa-loc{ opacity:.5; }
.ementa-group h4{
  font-family:Manrope,Arial,sans-serif;
  font-weight:600;
  font-size:11px;
  letter-spacing:.24em;
  text-transform:uppercase;
  padding-bottom:10px;
  margin-bottom:15px;
}
.ementa-group + .ementa-group{ margin-top:30px; }
.ementa-item{ padding:12px 0; }
.ei-name{ font-size:13px; letter-spacing:.004em; line-height:1.45; }
.ei-tag{ font-style:italic; text-transform:none; letter-spacing:0; opacity:.55; }
.ei-price{
  font-family:"Playfair Display",Georgia,serif;
  font-weight:500;
  font-size:14px;
}
.ei-dots{ opacity:.3; min-width:22px; }
.ementa-rail a{ font-weight:500; letter-spacing:.08em; text-transform:uppercase; font-size:10px; }
.ementa-fine{ letter-spacing:.06em; text-transform:uppercase; font-size:9px; opacity:.5; }
.ei-stamp{ border-radius:2px; font-weight:600; letter-spacing:.14em; transform:none; opacity:.9; }
.ementa-item.has-note::after{ opacity:.35; }

/* -- A. warm ivory — Taberna do Cais (jantar) -- */
.ementa-view[data-ementa="taberna"]{ background:#f7f3ea; color:#2b2620; }
.ementa-view[data-ementa="taberna"] .ementa-item + .ementa-item{ border-color:rgba(43,38,32,.12); }
.ementa-view[data-ementa="taberna"] .ementa-kicker{ color:#9a7b43; }
.ementa-view[data-ementa="taberna"] .ementa-group h4{
  color:#9a7b43;
  border-bottom:1px solid rgba(154,123,67,.35);
}
.ementa-view[data-ementa="taberna"] .ementa-rail{
  background:linear-gradient(#f7f3ea 60%,rgba(247,243,234,0));
}
.ementa-view[data-ementa="taberna"] .ementa-rail a{ color:rgba(43,38,32,.5); }
.ementa-view[data-ementa="taberna"] .ementa-rail a.is-active{ color:#f7f3ea; background:#2b2620; }
.ementa-view[data-ementa="taberna"] .ei-price{ color:#7a5c2e; }
.ementa-view[data-ementa="taberna"] .ei-stamp{ color:#8a3b32; border-color:#8a3b32; }

/* -- B. cool stone — Esplanada Marés (vinhos & bar) -- */
.ementa-view[data-ementa="esplanada"]{ background:#f4f4f3; color:#26262a; }
.ementa-view[data-ementa="esplanada"] .ementa-item + .ementa-item{ border-color:rgba(38,38,42,.1); }
.ementa-view[data-ementa="esplanada"] .ementa-kicker{ color:#6b7280; }
.ementa-view[data-ementa="esplanada"] .ementa-group h4{
  color:#3a3a40;
  border-bottom:1px solid rgba(38,38,42,.2);
}
.ementa-view[data-ementa="esplanada"] .ementa-rail{
  background:linear-gradient(#f4f4f3 60%,rgba(244,244,243,0));
}
.ementa-view[data-ementa="esplanada"] .ementa-rail a{ color:rgba(38,38,42,.5); }
.ementa-view[data-ementa="esplanada"] .ementa-rail a.is-active{ color:#f4f4f3; background:#26262a; }
.ementa-view[data-ementa="esplanada"] .ei-price{ color:#5b5f68; }
.ementa-view[data-ementa="esplanada"] .ei-stamp{ color:#8a3b32; border-color:#8a3b32; }

/* --- side panel: QR + benefits + CTA ---------------------------------- */
.ementa-side{
  display:flex;
  flex-direction:column;
  gap:16px;
  padding-top:6px;
  text-align:left;
}
.ementa-qr{
  margin:0;
  padding:14px;
  background:#fff;
  border-radius:16px;
  box-shadow:0 18px 40px rgba(0,0,0,.4);
  text-align:center;
}
.ementa-qr img{
  display:block;
  width:150px;
  height:150px;
  margin:0 auto;
}
.ementa-qr figcaption{
  margin-top:8px;
  font-size:11px;
  line-height:1.4;
  color:#3a4256;
  letter-spacing:.01em;
}
.ementa-benefits{
  list-style:none;
  margin:0;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:7px;
}
.ementa-benefits li{
  position:relative;
  padding-left:20px;
  font-size:12.5px;
  color:rgba(246,242,233,.82);
}
.ementa-benefits li::before{
  content:"";
  position:absolute;
  left:0;
  top:.42em;
  width:9px;
  height:9px;
  border-radius:2px;
  background:#e6b170;
  transform:rotate(45deg);
}
.ementa-cta{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:8px;
  padding:13px 20px;
  border-radius:999px;
  background:#f6f2e9;
  color:#12130f;
  font:700 13px/1 Manrope,Arial,sans-serif;
  letter-spacing:.01em;
  text-decoration:none;
  transition:transform .16s ease,box-shadow .16s ease;
}
.ementa-cta::after{ content:"\2192"; }
.ementa-cta:hover{ transform:translateY(-2px); box-shadow:0 12px 26px rgba(0,0,0,.35); }
.ementa-cta:focus-visible{ outline:2px solid #e6b170; outline-offset:3px; }

/* --- closing pitch band --------------------------------------------- */
.closing-pitch{
  background:#1a1512;
  color:#efe7d4;
  padding:clamp(64px,9vw,110px) 0;
  border-top:1px solid rgba(201,161,90,.22);
}
.closing-pitch-inner{
  display:flex;
  flex-direction:column;
  align-items:center;
  text-align:center;
  gap:14px;
}
.closing-pitch .section-index{
  color:#c9a15a;
  font:600 11px/1 "DM Mono",ui-monospace,monospace;
  letter-spacing:.2em;
  text-transform:uppercase;
  margin:0;
}
.closing-pitch-line{
  margin:0;
  font-family:"Playfair Display",Georgia,serif;
  font-weight:600;
  font-size:clamp(28px,4.4vw,50px);
  line-height:1.08;
}
.closing-pitch-sub{
  margin:0;
  max-width:46ch;
  font-size:15px;
  line-height:1.6;
  color:rgba(239,231,212,.72);
}
.closing-pitch-cta{
  margin-top:10px;
  display:inline-flex;
  align-items:center;
  gap:8px;
  padding:14px 26px;
  border-radius:999px;
  background:#c9a15a;
  color:#12130f;
  font:700 13px/1 Manrope,Arial,sans-serif;
  letter-spacing:.02em;
  text-decoration:none;
  transition:transform .16s ease,box-shadow .16s ease;
}
.closing-pitch-cta::after{ content:"\2192"; }
.closing-pitch-cta:hover{ transform:translateY(-2px); box-shadow:0 14px 30px rgba(0,0,0,.4); }
.closing-pitch-cta:focus-visible{ outline:2px solid #e6b170; outline-offset:3px; }

/* --- responsive ----------------------------------------------------- */
@media (max-width:860px){
  .ementa-stage{
    grid-template-columns:minmax(0,340px);
    gap:24px;
  }
  .ementa-side{
    align-items:center;
    text-align:center;
    max-width:340px;
    margin:0 auto;
  }
  .ementa-benefits{ align-items:center; }
}
@media (max-width:760px){
  .ementa-switch{ width:100%; max-width:340px; }
  .ementa-switch-btn{ flex:1; padding:10px 8px; font-size:12px; }
  .ementa-switch-btn span{ display:none; }
  .ementa-device{ padding:10px; border-radius:30px; }
  .ementa-device-notch{ width:74px; height:14px; top:16px; }
  .ementa-view{ border-radius:20px; }
  /* On a phone the menu is NOT its own scroll container — a tall (72vh)
     overflow:auto element in the middle of the viewport eats vertical
     swipes and makes the page feel stuck. Let it grow to full height and
     let the PAGE scroll normally. No touch-action:none anywhere here, so
     the page is never actually frozen — this just removes the friction. */
  .ementa-menu{
    max-height:none;
    overflow:visible;
    overscroll-behavior:auto;
    padding:46px 20px 26px;
  }
  .ementa-rail{ position:static; }
  .ementa-kicker{ letter-spacing:.12em; font-size:9px; }
  .ementa-casa{ margin-top:8px; }
  /* the video already moves (people, plates) — drop the ken-burns push on
     phones to save the GPU/battery during scroll */
  .ascii-bg-video{ animation:none !important; transform:scale(1.04) !important; }
}

/* --- reduced motion ----------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .ementa-switch-btn,
  .ementa-rail a,
  .ei-note,
  .ementa-cta,
  .closing-pitch-cta{ transition:none; }
  .ementa-cta:hover,
  .closing-pitch-cta:hover{ transform:none; }
}

/* === cookie-bar-polish.css === */
/* AUDIT_VISUAL_2026-09-02 P1: the consent card sat bottom-LEFT at a fixed
   480px and floated over the hero CTA and the first project card's controls
   at some scroll positions. Move it to the conventional bottom-centre — this
   layout keeps no primary action there — trim it, and slide it in. Desktop
   only; the <=760px stacked treatment (ios-safari-hardening.css) is unchanged,
   and it already hides .quick-actions while the bar is up. */
@media (min-width:761px){
  .cookie-bar{
    left:50%;
    right:auto;
    transform:translateX(-50%);
    bottom:20px;
    width:min(560px,calc(100% - 48px));
    padding:12px 16px;
    animation:cookieBarIn .4s ease both;
  }
  @keyframes cookieBarIn{
    from{ opacity:0; transform:translate(-50%,14px); }
    to{ opacity:1; transform:translate(-50%,0); }
  }
}
@media (prefers-reduced-motion:reduce){
  .cookie-bar{ animation:none !important; }
}

/* === assistant-launch-presence.css === */
/* 2026-09-02 — the discreet round launcher (audit-polish pt.1/pt.3) landed too
   quiet: a navy circle on a mostly-dark page barely read as interactive, so the
   chat entry point was easy to miss. Raise its presence WITHOUT undoing the
   "no 3D-robot render" decision: the site's ember action colour as a fixed 2px
   ring, plus a slow expanding pulse ring in the same motion vocabulary as the
   galo's galoBreathe. The ring is on box-shadow with !important because
   audit-polish already forces box-shadow !important on this element and CSS
   animations lose the cascade to !important author rules — so the pulse rides
   an ::after pseudo (free here: content is none), animating transform/opacity
   which nothing else touches. Both selectors match audit-polish's specificity
   and sit later in the file, so the static rule wins on source order. */
.quick-actions .assistant-launch,
.quick-actions .assistant-launch:hover{
  background:linear-gradient(150deg,#0c2848,#123a5f) !important;
  box-shadow:0 0 0 2px rgba(240,108,40,.92), 0 12px 26px rgba(4,12,26,.42) !important;
}
.quick-actions .assistant-launch:hover{
  box-shadow:0 0 0 2px #f06c28, 0 16px 30px rgba(4,12,26,.5) !important;
}
.quick-actions .assistant-launch>span:first-child{ color:#fff4ec !important; }
.quick-actions .assistant-launch::after{
  content:"";
  position:absolute;
  inset:0;
  border-radius:50%;
  border:2px solid rgba(240,108,40,.6);
  pointer-events:none;
  animation:assistantLaunchPulse 4.2s ease-out infinite;
}
@keyframes assistantLaunchPulse{
  0%{ transform:scale(1); opacity:.65; }
  70%,100%{ transform:scale(1.55); opacity:0; }
}
@media (prefers-reduced-motion:reduce){
  .quick-actions .assistant-launch::after{ animation:none !important; opacity:0 !important; }
}
