/* Public pages only. Keep the established TST greens and typography. */
.tst-project-page .section-header h2 { font-size: clamp(1.65rem, 3vw, 3rem); overflow-wrap: anywhere; text-wrap: balance; }
.tst-project-page .section-header p { font-size: 1rem; }
.tst-public-home #clientes { padding-block: 3.5rem !important; }
.tst-public-home #clientes .section-header { margin-bottom: 2rem; }
.tst-public-home #clientes .section-header h2 { font-size: clamp(1.8rem, 3vw, 2.5rem); }
.tst-public-home .campanas-header h2 { font-size: clamp(2rem, 4vw, 3.5rem) !important; font-weight: 600 !important; letter-spacing: -.035em; }
.tst-public-home .campanas-header p { max-width: 58ch; margin-inline: auto; line-height: 1.6; }
.tst-public-home .reconocimientos-content { display: grid; grid-template-columns: .75fr 1.25fr; gap: 3rem; align-items: center; }
.tst-public-home .reconocimiento-badge-icon { margin-inline: 0; width: 52px; height: 52px; font-size: 1.6rem; margin-bottom: 1.5rem; }
.tst-public-home .reconocimiento-text { text-align: left; margin: 0; }
.tst-public-home .reconocimiento-lead { font-size: 1.05rem; line-height: 1.7; }
.tst-public-home .reconocimiento-sub { font-size: .9rem; line-height: 1.7; margin-top: 1rem; }
.tst-public-home .reconocimientos-grid { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 1rem; }
.tst-public-home .reconocimiento-item { padding: 0; min-width: 0; border: 1px solid #ffffff30; border-radius: 12px; overflow: hidden; background: #0e2e2a; cursor: zoom-in; color: white; }
.tst-public-home .reconocimiento-img-wrapper { height: auto; aspect-ratio: 4/3; padding: .75rem; }
.tst-public-home .reconocimiento-img-wrapper img { width: 100%; height: 100%; object-fit: contain; }
.video-editorial { display: grid; grid-template-columns: .7fr 1.3fr; gap: 3rem; align-items: center; }
.video-copy h2 { font: 600 clamp(2rem, 3.5vw, 3.25rem)/1.1 'Montserrat', sans-serif; color: white; letter-spacing: -.045em; margin: 1.25rem 0; }
.video-copy h2 span { color: #a8ebd0; }
.video-copy p { color: #cbe3d8; font-size: 1rem; line-height: 1.7; margin-bottom: 1.5rem; }
.video-editorial .video-wrapper { border-radius: 12px; overflow: hidden; }
.tst-public-home .faq-container { gap: 3rem; }
.tst-public-home .faq-left h2 { font-size: clamp(2rem, 3.5vw, 3.2rem); font-weight: 600; letter-spacing: -.035em; }
.tst-public-home .faq-question { font-size: .95rem; min-height: 60px; line-height: 1.5; padding: 1.2rem; text-align: left; }
.tst-public-home .faq-answer-inner { font-size: .92rem; }
.tst-public-home .contact-editorial { display: grid; grid-template-columns: .7fr 1.3fr; gap: 3rem; align-items: center; }
.tst-public-home .contact-editorial .section-header { text-align: left; margin: 0; }
.tst-public-home .contact-editorial .section-header h2 { font-size: clamp(2rem, 3.3vw, 3.2rem); font-weight: 600; letter-spacing: -.035em; }
.tst-public-home .contact-editorial .section-header p { margin-inline: 0; font-size: 1rem; }
.tst-public-home .contact-editorial .section-header .contact-explainer { font-size: .85rem; color: #bad8ca; margin-top: 1.5rem; }
.tst-public-home .contact-editorial .contact-form-container { width: 100%; background: #173e35; border: 1px solid #ffffff25; border-radius: 16px; box-shadow: none; }
:is(.tst-public-home, .tst-project-page) .tst-footer-grid { gap: 1.75rem; }
:is(.tst-public-home, .tst-project-page) .tst-footer-grid > * { min-width: 0; }
:is(.tst-public-home, .tst-project-page) footer a { overflow-wrap: anywhere; }
@media (max-width: 900px) {
  .tst-public-home .reconocimientos-content, .video-editorial, .tst-public-home .contact-editorial { grid-template-columns: 1fr; gap: 2rem; }
  .tst-public-home .reconocimientos-content { max-width: 760px; margin: auto; }
}
@media (max-width: 600px) {
  .tst-public-home .reconocimientos-grid { gap: .75rem; }
  .tst-public-home .reconocimiento-img-wrapper { aspect-ratio: 3/4; padding: .4rem; }
  .tst-public-home .faq-container { gap: 2rem; }
  .tst-public-home .faq-question { font-size: .9rem; }
  .tst-public-home .contact-editorial .contact-form-container { padding: 1.25rem; }
  .tst-public-home .video-copy h2 { font-size: 2rem; }
}
:is(.tst-public-home, .tst-project-page) .editorial-header .lang-toggle { display: inline-flex !important; }
.tst-project-page .pd-benefit-shine { display: none; }
.tst-project-page .pd-hero-image-mobile { max-height: 420px; width: auto; }
.tst-project-page .pd-hero-image-glow { display: none; }
.tst-project-page .pd-stats-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.tst-project-page .pd-stat-card { padding: 1rem .75rem; min-width: 0; }
.tst-project-page .pd-stat-value { font-size: 2rem; }
.tst-project-page .pd-stat-label { font-size: .75rem; overflow-wrap: anywhere; }
@media (max-width: 600px) {
  .tst-project-page .pd-stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tst-project-page .pd-hero-image-mobile { max-height: 360px; max-width: 180px; }
}
.project-back-link { grid-column: 1; grid-row: 1; justify-self: start; display: flex; align-items: center; min-height: 44px; gap: .75rem; color: white; text-decoration: none; font-size: .85rem; }
.tst-project-page .editorial-header .brand-text { display: block; }
.tst-public-home .services-editorial-banner { position: relative; isolation: isolate; overflow: hidden; min-height: 470px; display: flex; align-items: center; justify-content: flex-end; padding: 3rem; border-radius: 16px; margin-bottom: 2.5rem; }
.services-editorial-banner > img { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; object-fit: cover; }
.services-editorial-banner::after { content: ''; position: absolute; inset: 0; z-index: -1; background: linear-gradient(90deg, transparent 20%, #0a251ee6 70%); }
.tst-public-home .services-editorial-copy { max-width: 520px; text-align: left; }
.tst-public-home .services-editorial-copy h2 { font-size: clamp(2rem, 3.3vw, 3.2rem); line-height: 1.1; letter-spacing: -.04em; text-wrap: balance; }
.tst-public-home .services-editorial-copy p { font-size: 1rem; margin-inline: 0; max-width: 45ch; }
@media (max-width: 600px) {
  .project-back-link { width: 44px; justify-content: center; }
  .project-back-link > span { display: none; }
  .tst-public-home .services-editorial-banner { min-height: 520px; padding: 1.5rem; align-items: flex-end; }
  .services-editorial-banner > img { object-position: 28% center; }
  .services-editorial-banner::after { background: linear-gradient(0deg, #0a251efa 10%, #0a251e55 100%); }
}
:is(.tst-public-home, .tst-project-page) .editorial-header { background: #0e2e2aeb; border-bottom: 1px solid #ffffff24; box-shadow: none; }
:is(.tst-public-home, .tst-project-page) .editorial-header.scrolled { background: #0e2e2af5; }
:is(.tst-public-home, .tst-project-page) .editorial-header > nav { display: grid; grid-template-columns: minmax(0,1fr) auto minmax(0,1fr); gap: 1rem; min-height: 88px; max-width: none; padding: .75rem 2.5rem !important; }
:is(.tst-public-home, .tst-project-page) .editorial-header .logo-link { grid-column: 2; grid-row: 1; justify-self: center; }
:is(.tst-public-home, .tst-project-page) .editorial-header .mobile-menu-btn { grid-column: 1; grid-row: 1; display: flex !important; justify-self: start; width: 44px; height: 44px; align-items: center; justify-content: center; color: white; border-color: #ffffff30; background: transparent; }
:is(.tst-public-home, .tst-project-page) .editorial-header .nav-links { display: none !important; }
:is(.tst-public-home, .tst-project-page) .editorial-header .nav-actions { grid-column: 3; grid-row: 1; justify-self: end; gap: .65rem; }
:is(.tst-public-home, .tst-project-page) .editorial-header .logo-container img { filter: brightness(0) invert(1); height: 44px; }
:is(.tst-public-home, .tst-project-page) .editorial-header .public-brand-name { font: 700 1.6rem/1 'Montserrat', sans-serif; color: #fff; }
:is(.tst-public-home, .tst-project-page) .editorial-header .brand-text p { color: #c2e6da; font-size: .55rem; letter-spacing: .07em; }
:is(.tst-public-home, .tst-project-page) .editorial-header .nav-login, :is(.tst-public-home, .tst-project-page) .editorial-header .lang-toggle { background: transparent; border-color: #ffffff30; color: #fff; }
:is(.tst-public-home, .tst-project-page) .editorial-header .lang-toggle span { color: #a8c7bd; }
:is(.tst-public-home, .tst-project-page) .editorial-header .lang-toggle span.active { color: #8ff3d9; }
:is(.tst-public-home, .tst-project-page) .editorial-header .nav-cta { display: none; }
.tst-public-home .mobile-nav { left: -100%; right: auto; transition: left .25s ease; visibility: hidden; }
.tst-public-home .mobile-nav.active { left: 0; right: auto; visibility: visible; }
.purpose-editorial { display: grid; grid-template-columns: .9fr 1.1fr; align-items: center; gap: clamp(2rem, 5vw, 5rem); }
.purpose-copy h2 { font: 600 clamp(2rem, 3.3vw, 3.2rem)/1.13 'Montserrat', sans-serif; letter-spacing: -.04em; margin: 1.2rem 0 1.4rem; color: #fff; text-wrap: balance; }
.purpose-copy h2 span { color: #b6f7df; }
.purpose-copy > p { max-width: 48ch; font-size: 1rem; line-height: 1.75; color: #e0f1e9; }
.purpose-outcomes { list-style: none; padding: 0; margin: 1.75rem 0 2rem; display: grid; gap: .85rem; }
.purpose-outcomes li { display: flex; align-items: baseline; gap: .7rem; font-size: .9rem; line-height: 1.5; color: #eef7f2; }
.purpose-outcomes i { color: #a4f9d9; font-size: .8rem; }
.purpose-visual { margin: 0; min-width: 0; padding: 1.25rem; border-radius: 16px; background: #103e35; }
.purpose-visual img { display: block; width: 100%; height: auto; aspect-ratio: 2048/1123; object-fit: contain; border-radius: 6px; }
.purpose-visual figcaption { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 1.25rem .2rem .15rem; }
.purpose-visual figcaption span { display: block; font-size: .55rem; letter-spacing: .13em; color: #b0d9ca; margin-bottom: .4rem; }
.purpose-visual figcaption strong { font-size: 1rem; color: #fff; font-weight: 500; }
.purpose-visual figcaption a { color: #c4f8e3; text-decoration: none; font-size: .8rem; min-height: 44px; display: flex; align-items: center; gap: .6rem; white-space: nowrap; }
.history-heading { text-align: center; margin-bottom: 2.5rem; }
.history-heading h2 { font: 600 clamp(2rem, 3.5vw, 3.25rem)/1.1 'Montserrat', sans-serif; letter-spacing: -.04em; color: #fff; margin: 1rem 0; }
.history-heading p { font-size: .95rem; color: #d9ede4; }
.history-tabs { position: relative; display: flex; overflow-x: auto; scrollbar-width: thin; scrollbar-color: #a6e8cc #ffffff20; gap: 0; margin-bottom: 2.5rem; padding: .3rem .2rem 1rem; }
.history-tabs button { position: relative; flex: 1 0 80px; min-height: 70px; padding: .5rem 0 1.4rem; background: none; border: none; color: #c4e0d4; cursor: pointer; font: 500 1rem 'Montserrat', sans-serif; }
.history-tabs button::after { content: ''; position: absolute; height: 1px; background: #c4e0d460; bottom: 10px; left: 0; right: 0; }
.history-dot { width: 10px; height: 10px; border-radius: 50%; background: #1f6f63; border: 1px solid #c4e0d4; position: absolute; bottom: 5px; left: calc(50% - 5px); z-index: 1; }
.history-tabs button[aria-selected="true"] { color: #fff; font-weight: 700; }
.history-tabs button[aria-selected="true"] .history-dot { background: #b5f7d7; border-color: #b5f7d7; box-shadow: 0 0 0 5px #b5f7d71a; }
.history-panel[hidden] { display: none; }
.history-panel:not([hidden]) { display: grid; grid-template-columns: .65fr 1.35fr; gap: 3rem; align-items: start; min-height: 275px; max-width: 1040px; margin: 0 auto; }
.history-year-display { font: 600 clamp(4.5rem, 8vw, 8rem)/1 'Montserrat', sans-serif; letter-spacing: -.07em; color: #a1ebca; }
.history-year-display > span { display: block; font: 500 .6rem 'Inter', sans-serif; letter-spacing: .2em; color: #c3e8d6; margin-top: 1rem; }
.history-story h3 { font: 600 clamp(1.4rem, 2.4vw, 2rem)/1.2 'Montserrat', sans-serif; color: #fff; margin-bottom: 1.25rem; }
.history-story p, .history-story li { color: #e0f1e8; line-height: 1.75; font-size: .95rem; }
.history-more summary { cursor: pointer; color: #b5f7d7; padding: 1rem 0; font-size: .85rem; min-height: 44px; }
.history-more ul { padding-left: 1.25rem; margin-bottom: 1rem; }
@media (max-width: 900px) {
  .purpose-editorial { grid-template-columns: 1fr; gap: 2rem; }
  .purpose-copy { max-width: 620px; }
  .purpose-visual { max-width: 700px; }
  :is(.tst-public-home, .tst-project-page) .editorial-header .nav-login span { display: none; }
  :is(.tst-public-home, .tst-project-page) .editorial-header .nav-login { min-width: 44px; min-height: 44px; padding: .65rem; justify-content: center; }
  :is(.tst-public-home, .tst-project-page) .editorial-header .brand-text p { display: none; }
}
@media (max-width: 600px) {
  :is(.tst-public-home, .tst-project-page) .editorial-header > nav { gap: .25rem; padding: .5rem .75rem !important; min-height: 72px; }
  :is(.tst-public-home, .tst-project-page) .editorial-header .logo-container { gap: .4rem; }
  :is(.tst-public-home, .tst-project-page) .editorial-header .public-brand-name { font-size: 1.25rem; }
  :is(.tst-public-home, .tst-project-page) .editorial-header .logo-container img { height: 30px !important; }
  :is(.tst-public-home, .tst-project-page) .editorial-header .nav-login { display: none; }
  :is(.tst-public-home, .tst-project-page) .editorial-header .lang-toggle { min-height: 44px; padding: .35rem .5rem; font-size: .65rem; gap: .15rem; }
  :is(.tst-public-home, .tst-project-page) .editorial-header .lang-toggle > i { display: none; }
  .purpose-copy h2 { font-size: 2rem; }
  .purpose-visual { padding: .75rem; }
  .purpose-visual figcaption { gap: .5rem; }
  .purpose-visual figcaption span { font-size: .5rem; }
  .purpose-visual figcaption strong { font-size: .9rem; }
  .purpose-visual figcaption a { font-size: .7rem; }
  .history-panel:not([hidden]) { grid-template-columns: 1fr; gap: 1.5rem; min-height: 360px; }
  .history-year-display { font-size: 4.5rem; }
  .history-year-display > span { display: none; }
}
.tst-public-home #inicio.editorial-hero { position: relative; isolation: isolate; min-height: min(880px, 100svh); min-height: max(700px, min(880px, 100svh)); display: flex; align-items: flex-end; padding-top: 12rem !important; padding-bottom: 7rem !important; }
.editorial-hero-image, .editorial-hero-shade { position: absolute; inset: 0; width: 100%; height: 100%; }
.editorial-hero-image { object-fit: cover; object-position: center; z-index: -2; }
.editorial-hero-shade { z-index: -1; background: linear-gradient(90deg, #09231eed 0%, #0e2e2a80 43%, #0e2e2a08 75%), linear-gradient(0deg, #0e2e2a 0%, transparent 32%); }
.editorial-hero-copy { max-width: 850px; width: 100%; }
.tst-public-home #inicio.editorial-hero { justify-content: flex-start; }
.editorial-eyebrow { font-size: .72rem; letter-spacing: .2em; font-weight: 600; margin-bottom: 1.5rem; color: #bde9dc; }
.tst-public-home .editorial-hero h1 { font: 600 clamp(3.5rem, 6.4vw, 6.4rem)/1.02 'Montserrat', sans-serif; letter-spacing: -.055em; color: #fff; text-wrap: balance; }
.editorial-hero h1 span { color: #8ff3d9; }
.editorial-hero-description { color: #eef7f3; font-size: clamp(1rem, 1.4vw, 1.2rem); line-height: 1.65; margin-top: 1.8rem; max-width: 520px; }
.editorial-hero-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 1rem 1.75rem; margin-top: 2rem; }
.editorial-text-link { color: #fff; font-size: .9rem; text-decoration: none; display: inline-flex; align-items: center; gap: .75rem; min-height: 44px; border-bottom: 1px solid #ffffff65; }
.editorial-text-link:hover { color: #8ff3d9; }
.editorial-hero-footnote { position: absolute; bottom: 1.5rem; left: max(1.25rem, calc((100% - 1280px) / 2)); right: max(1.25rem, calc((100% - 1280px) / 2)); display: flex; align-items: center; justify-content: space-between; gap: .75rem; border-top: 1px solid #ffffff30; padding-top: .75rem; color: #bde9dc; font-size: .65rem; letter-spacing: .15em; }
.editorial-hero-footnote a { display: grid; place-items: center; width: 44px; height: 44px; flex-shrink: 0; color: #8ff3d9; text-decoration: none; }
.editorial-split { display: grid; grid-template-columns: .85fr 1.15fr; align-items: center; gap: 3rem; margin-bottom: 2.5rem; }
.tst-public-home .editorial-split .section-header { text-align: left; margin: 0; }
.tst-public-home .editorial-split .section-header h2 { font-size: clamp(1.9rem, 3vw, 3rem); letter-spacing: -.035em; line-height: 1.15; }
.tst-public-home .editorial-split .section-header p { margin-inline: 0; }
.editorial-case-image { display: block; min-width: 0; overflow: hidden; border-radius: 12px; text-decoration: none; background: #0e2e2a; }
.editorial-case-image img { display: block; width: 100%; height: auto; aspect-ratio: 16/10; object-fit: cover; object-position: top; transition: filter .2s ease; }
.editorial-case-image:hover img { filter: brightness(1.08); }
.editorial-case-image > span { display: flex; justify-content: space-between; gap: .75rem; padding: 1rem 1.2rem; color: #d7f3e9; font-size: .85rem; }
@media (max-width: 760px) {
  .editorial-hero-image { object-position: 66% center; }
  .editorial-hero-shade { background: linear-gradient(0deg, #0e2e2a 0%, #0e2e2acf 40%, #0e2e2a20 100%); }
  .tst-public-home #inicio.editorial-hero { min-height: max(740px, 100svh); padding-top: 16rem !important; }
  .tst-public-home .editorial-hero h1 { font-size: clamp(2.7rem, 8.3vw, 4rem); }
  .editorial-hero-actions .btn { padding-inline: 1.2rem; font-size: .87rem; }
  .editorial-hero-footnote { font-size: .55rem; letter-spacing: .08em; }
}
.tst-public-home > section[data-tone="dark"] { --home-section-bg: #0e2e2a; }
.tst-public-home > section[data-tone="light"] { --home-section-bg: #1f6f63; }
.tst-public-home > section[data-tone] {
  background-color: var(--home-section-bg) !important;
  background-image: none !important;
  padding: clamp(3rem, 5vw, 5rem) max(1.25rem, calc((100% - 1280px) / 2)) !important;
}
.tst-public-home > section#inicio { padding-top: 8rem !important; }
.tst-public-home > section#campanas { padding-inline: 0 !important; }
.tst-public-home .section-header { margin-bottom: 2.5rem; }
.tst-public-home .software-category-header { margin-bottom: 1.25rem; }
.showcase-controls { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin: 0 auto 1rem; max-width: 1280px; color: #bce9dc; font-size: .85rem; }
.tst-public-home .home-showcase { display: flex !important; flex-direction: row; gap: 1.25rem; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x proximity; overscroll-behavior-x: contain; padding: .25rem .2rem 1.25rem; max-width: 1280px; scrollbar-width: thin; scrollbar-color: #3fae9a #0e2e2a; }
.tst-public-home .home-showcase > * { flex: 0 0 calc((100% - 2.5rem) / 3); width: auto; min-width: 0; scroll-snap-align: start; margin: 0; }
.tst-public-home .home-showcase .software-card-mobile { flex-basis: calc((100% - 1.25rem) / 2); padding: 1.5rem; border-radius: 16px; }
.tst-public-home .software-img-mobile-wrapper { max-width: 150px; }
.tst-public-home .software-img-mobile { max-height: 280px; }
.tst-public-home .software-img-mobile img { object-fit: contain; }
.tst-public-home .software-info-mobile h3 { font-size: 1.2rem; }
.tst-public-home .software-info-mobile p, .tst-public-home .software-info p { font-size: .9rem; }
.tst-public-home .software-img-web { height: 230px; }
.tst-public-home .software-info { padding: 1.25rem; }
.tst-public-home .software-info h3 { font-size: 1.2rem; }
.case-title-link { color: inherit; text-decoration: none; }
.case-title-link:hover { text-decoration: underline; }

@media (max-width: 900px) {
  .tst-public-home .home-showcase > * { flex-basis: calc((100% - 1.25rem) / 2); }
  .tst-public-home .home-showcase .software-card-mobile { flex-basis: calc(100% - 2rem); }
}
@media (max-width: 600px) {
  .tst-public-home .home-showcase > * { flex-basis: calc(100% - 1.5rem); }
  .tst-public-home .home-showcase .software-card-mobile { flex-basis: calc(100% - 1.5rem); padding: 1.25rem; }
  .tst-public-home .software-img-web { height: 190px; }
  .tst-public-home .software-img-mobile-wrapper { max-width: 110px; }
  .tst-public-home .software-info-mobile h3 { font-size: 1.05rem; }
}
.tst-public-home .fade-in, .tst-project-page .fade-in {
  opacity: 1 !important;
  transform: none !important;
  animation: none !important;
}

.tst-public-home .section-anchor { display: block; scroll-margin-top: 100px; }
.tst-public-home #infraestructura { scroll-margin-top: 120px; }
.tst-public-home .services-mini-grid { align-items: start; }
.service-details { text-align: left; margin-top: 1rem; border-top: 1px solid #ffffff26; }
.service-details summary { cursor: pointer; padding: .8rem 0; color: #8ff3d9; font-size: .85rem; font-weight: 600; }
.service-details p { margin-top: .7rem; }
.section-shortcuts { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; margin-top: 1.25rem; }
.section-shortcuts a { display: inline-flex; align-items: center; min-height: 44px; padding: .5rem 1rem; border: 1px solid #ffffff40; border-radius: 30px; color: white; font-size: .85rem; text-decoration: none; }
.section-shortcuts a:hover { background: #ffffff15; }
.tst-public-home .timeline-item { width: 100% !important; left: 0 !important; padding: 0 !important; margin: 0; }
.tst-public-home .timeline-year { position: static; font-size: .9rem !important; margin-bottom: .75rem; color: #8ff3d9; }
.tst-public-home .contact-form-container { max-width: 860px; padding: 2rem; margin-bottom: 0; }
.tst-public-home #contactForm { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.2rem; }
.tst-public-home #contactForm .form-group { margin: 0; min-width: 0; }
.tst-public-home #contactForm .form-group:has(textarea), .tst-public-home #contactForm .form-btn { grid-column: 1 / -1; }
.tst-public-home .form-control { width: 100%; min-width: 0; font-size: 1rem; }
.tst-public-home :focus-visible, .tst-project-page :focus-visible { outline: 3px solid #8ff3d9; outline-offset: 4px; }

/* One shared, non-autoplay gallery for every mobile and web project. */
.tst-project-page > section { padding: clamp(2.5rem, 5vw, 4.5rem) max(1.25rem, calc((100% - 1280px) / 2)); }
.tst-project-page .section-header { margin-bottom: 2rem; }
.tst-project-page .pd-hero { padding-top: 8rem; min-height: auto; }
.tst-project-page .pd-hero-layout { gap: clamp(1.5rem, 4vw, 4rem); }
.tst-project-page .pd-title { font-size: clamp(2rem, 3.5vw, 3.5rem); overflow-wrap: anywhere; }
.tst-project-page .pd-hero-image-mobile { max-width: 280px; margin-inline: auto; }
.tst-project-page .pd-hero-image img { object-fit: contain; }
.tst-project-page .pd-hero-image:hover img { transform: none; }
.tst-project-page .pd-scroll-indicator { display: none; }
.tst-project-page .pd-breadcrumb { flex-wrap: wrap; margin-bottom: 1.5rem; }
.tst-project-page .pd-features-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; }
.tst-project-page .pd-feature-card { padding: 1.5rem; }
.tst-project-page .pd-feature-card h3 { font-size: 1rem; }
.tst-project-page .pd-tech-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; }
.tst-project-page .pd-tech-card { padding: 1.25rem; }
.tst-project-page .pd-benefits-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; }
.tst-project-page .pd-benefit-card { padding: 1.5rem; }
.project-gallery-toolbar, .project-viewer-toolbar, .project-viewer-footer { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.project-gallery-toolbar { max-width: 1280px; margin: 0 auto 1rem; color: #bce9dc; font-variant-numeric: tabular-nums; }
.project-gallery-buttons { display: flex; gap: .5rem; }
.gallery-control { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; flex: 0 0 44px; padding: 0; border: 1px solid #ffffff40; border-radius: 50%; background: #ffffff0c; color: #fff; cursor: pointer; font-size: 1rem; }
.gallery-control:hover:not(:disabled) { background: #3fae9a40; border-color: #8ff3d9; }
.gallery-control:disabled { opacity: .3; cursor: default; }
.project-gallery-track { display: flex; gap: 1.25rem; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x proximity; overscroll-behavior-x: contain; padding: .35rem .2rem 1rem; scrollbar-width: thin; scrollbar-color: #3fae9a #0e2e2a; max-width: 1280px; margin: auto; }
.project-gallery-slide { scroll-snap-align: start; flex: 0 0 76%; min-width: 0; max-width: 880px; padding: 0; border: 1px solid #ffffff30; border-radius: 16px; overflow: hidden; background: #102e2a; color: #fff; cursor: zoom-in; font: inherit; text-align: left; }
.is-mobile-gallery .project-gallery-slide { flex-basis: 245px; }
.project-gallery-preview { display: flex; align-items: center; justify-content: center; aspect-ratio: 16 / 10; background: #09221f; padding: .75rem; }
.is-mobile-gallery .project-gallery-preview { aspect-ratio: 9 / 16; }
.project-gallery-preview img { display: block; width: 100%; height: 100%; object-fit: contain; }
.project-gallery-caption { display: flex; justify-content: space-between; gap: .75rem; padding: 1rem 1.25rem; font-size: .85rem; color: #c6eee3; }
.project-viewer:not([open]) { display: none; }
.project-viewer[open] { display: flex; flex-direction: column; gap: .8rem; }
.project-viewer { width: min(1240px, calc(100vw - 2rem)); max-width: none; height: min(920px, calc(100dvh - 2rem)); max-height: none; margin: auto; padding: 1rem; border: 1px solid #3fae9a70; border-radius: 20px; background: #0b2723; color: #fff; overflow: hidden; }
.project-viewer::backdrop { background: #03130feb; }
.project-viewer-stage { min-height: 0; flex: 1; overflow: auto; overscroll-behavior: contain; border-radius: 8px; background: #071d19; }
.project-viewer-stage img { display: block; width: 100%; height: 100%; object-fit: contain; margin: auto; }
.project-viewer-stage.is-zoomed img { width: 200%; max-width: none; height: auto; min-height: 100%; object-fit: contain; }
.project-viewer-footer { color: #c6eee3; font-size: .8rem; }
@media (max-width: 900px) {
  .tst-project-page .pd-hero-layout { grid-template-columns: 1fr; }
  .tst-project-page .pd-hero-image-web { max-width: 650px; margin-inline: auto; }
  .tst-project-page .pd-features-grid, .tst-project-page .pd-tech-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
  .tst-public-home > section[data-tone], .tst-project-page > section { padding-inline: 1.25rem !important; }
  .tst-public-home #contactForm { grid-template-columns: 1fr; }
  .tst-public-home .contact-form-container { padding: 1.25rem; }
  .tst-project-page .pd-features-grid, .tst-project-page .pd-tech-grid, .tst-project-page .pd-benefits-grid { grid-template-columns: 1fr; }
  .tst-project-page .pd-feature-card { display: flex; align-items: center; gap: 1rem; padding: 1.25rem; }
  .tst-project-page .pd-feature-icon { width: 32px; height: 32px; font-size: 1.25rem; flex-shrink: 0; margin: 0; }
  .tst-project-page .pd-feature-number { display: none; }
  .tst-project-page .pd-feature-card h3 { margin: 0; text-align: left; }
  .tst-project-page .pd-benefit-card { display: flex; text-align: left; gap: 1rem; align-items: center; }
  .tst-project-page .pd-benefit-icon { width: 32px; height: 32px; font-size: 1.25rem; flex-shrink: 0; margin: 0; }
  .tst-project-page .pd-actions .btn { width: 100%; white-space: normal; }
  .tst-project-page .pd-hero-info { min-width: 0; }
  .tst-project-page .nav-actions { gap: .4rem; }
  .project-gallery-slide { flex-basis: calc(100% - 16px); }
  .is-mobile-gallery .project-gallery-slide { flex-basis: min(235px, calc(100% - 16px)); }
  .project-viewer { width: calc(100vw - 1rem); height: calc(100dvh - 1rem); border-radius: 12px; padding: .75rem; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto !important; }
  .tst-public-home *, .tst-project-page * { animation: none !important; transition: none !important; }
}

/* Compact public catalogue; avoid inheriting the old full-width app layout. */
.tst-public-home .home-showcase { align-items: stretch; }
.tst-public-home .home-showcase .software-card-web { height: auto; align-self: stretch; }
.tst-public-home .software-card-web .software-img-web { flex-shrink: 0; }
.tst-public-home .software-card-web .software-info h3 { min-height: 2.5em; line-height: 1.25; text-transform: none; }
.tst-public-home .software-card-actions { display: flex; align-items: center; justify-content: space-between; gap: .6rem; min-height: 44px; margin-top: auto; }
.tst-public-home .software-card-actions .software-tech { align-self: center; padding-inline: .8rem; }
.tst-public-home .software-card-actions :is(.software-demo-btn, .software-oficial-btn, .software-cta) { margin: 0; min-height: 44px; display: inline-flex; align-items: center; font-size: .8rem; }
.tst-public-home .software-card-actions :is(.software-demo-btn, .software-oficial-btn) { padding: .6rem .8rem; }
.tst-public-home .home-showcase .software-card-mobile { grid-template-columns: minmax(105px, .6fr) minmax(0, 1fr); align-items: center; gap: 1.5rem; min-height: 330px; }
.tst-public-home .software-img-mobile-wrapper { width: 100%; padding: 0; justify-self: center; background: none; }
.tst-public-home .software-img-mobile { height: 260px; }
.tst-public-home .software-img-mobile img { max-width: 100%; height: 100%; }
.tst-public-home .software-info-mobile { min-width: 0; padding: 0; gap: .6rem; }
.tst-public-home .software-info-mobile h3 { text-transform: none; line-height: 1.25; overflow-wrap: anywhere; }
.tst-public-home .software-category-header { text-align: left; margin-top: 2rem; }
.tst-public-home .software-category-icon { display: none; }
.tst-public-home .software-category-header h3 { font-size: 1.5rem; }
.tst-public-home #proyectos .section-header { margin-bottom: 2rem; }
.tst-public-home .mobile-nav-footer { display: block; }
.tst-public-home .contact-status { grid-column: 1 / -1; font-size: .9rem; line-height: 1.6; color: #d5f6e6; margin: 0; }
.tst-public-home .contact-status a { color: #a6f4d9; text-decoration: underline; }
@media (max-width: 760px) {
  .editorial-split { grid-template-columns: 1fr; gap: 1.5rem; }
}
@media (max-width: 600px) {
  .tst-public-home .home-showcase .software-card-mobile { grid-template-columns: 1fr !important; gap: 1rem; }
  .tst-public-home .software-img-mobile { height: 220px; }
  .tst-public-home .software-info-mobile { text-align: left; }
  .tst-project-page .pd-hero-image-mobile { max-width: 180px; }
}

/* ==========================================================================
   Lenguaje editorial (referencia: astonmartinf1.com)
   --------------------------------------------------------------------------
   Las dos secciones que ya funcionaban -- trayectoria y "TST en accion" --
   comparten una misma receta: antetitulo diminuto con mucho tracking, titular
   grande de peso medio (no negrita) con tracking negativo, reparto asimetrico y
   filetes de 1px en vez de cajas. Aqui se extiende esa receta al resto de la
   home para que la pagina se lea como una sola pieza y no como bloques sueltos.

   Tokens que ya existian y se reutilizan:
     antetitulo  .72rem / ls .2em / 600 / #bde9dc
     titular     Montserrat 600 / clamp(2rem,3.5vw,3.25rem) / lh 1.1 / ls -.04em
     acento      #a8ebd0        filete  #ffffff1f
   ========================================================================== */

/* Antetitulo: la pildora centrada se convierte en etiqueta editorial. */
.tst-public-home .section-label {
  display: inline-block; background: none !important; border: 0 !important;
  padding: 0 !important; border-radius: 0 !important;
  font-size: .72rem; font-weight: 600; letter-spacing: .2em; text-transform: uppercase;
  color: #bde9dc; margin-bottom: 1.25rem;
}

/* Titular editorial: peso medio, no 800. La negrita gruesa era lo que hacia
   ver estas secciones como plantilla. */
.tst-public-home .section-header h2,
.tst-public-home .services-editorial-copy h2 {
  font-family: Montserrat, sans-serif; font-weight: 600 !important;
  line-height: 1.1; letter-spacing: -.04em; text-wrap: balance;
}

/* Encabezados alineados a la izquierda: el centrado era lo que mas delataba
   la plantilla. */
.tst-public-home .section-header {
  text-align: left; max-width: 62ch; margin-inline: 0;
}
.tst-public-home .section-header p { margin-inline: 0; max-width: 56ch; }

/* --------------------------------------------------------------- clientes */
/* Los 14 logos vienen en colores y tipografias distintas; juntos se veian como
   un collage. En blanco monocromo quedan como un muro de socios coherente, y
   cada uno recupera su color al pasar el raton. */
.tst-public-home #clientes .section-header { display: grid; gap: .25rem; }
.tst-public-home #clientes .section-header p { margin-inline: 0; max-width: 52ch; }
.tst-public-home .clients-marquee {
  border-top: 1px solid #ffffff26; border-bottom: 1px solid #ffffff26;
  padding-block: 2.25rem; margin-top: 2.5rem;
}
.tst-public-home .clients-track { gap: 3rem; }
.tst-public-home .clients-track .client-logo {
  width: 210px; border: 0 !important; box-shadow: none !important;
  /* Base clara muy tenue: varios logotipos son de tinta oscura (Integracorp,
     INJEB, Northospital, Dominus) y sobre el verde medio se perdian. No vuelve
     a ser la tarjeta blanca de antes -- sin borde, sin sombra y con esquina
     minima -- pero devuelve el contraste sin tocar el color de cada marca. */
  background: #ffffffed !important;
  border-radius: 6px !important;
  padding: 1.1rem 1.35rem !important;
  display: flex !important; align-items: center; justify-content: center;
  transition: background-color .3s ease, transform .35s cubic-bezier(.2, .8, .2, 1);
}
.tst-public-home .clients-track .client-logo:hover {
  background: #ffffff !important; transform: translateY(-3px);
}
/* Cada marca con su color. Se probo el blanco monocromo -- que es lo que hacen
   los muros de patrocinadores -- pero el usuario prefiere reconocer cada
   identidad, asi que solo se atenua un poco y se realza al pasar el raton. */
.tst-public-home .clients-track .client-logo img {
  filter: none; opacity: .92;
  transition: opacity .35s ease;
  max-height: 58px; width: 100%; object-fit: contain;
}
.tst-public-home .clients-track .client-logo:hover img { opacity: 1; }

/* Cifras al pie: un dato concreto pesa mas que un adjetivo. */
.clients-meta {
  display: flex; flex-wrap: wrap; gap: 3rem; margin-top: 1.75rem;
  font-size: .78rem; letter-spacing: .06em; text-transform: uppercase; color: #a9d9cb;
}
.clients-meta b {
  display: block; font-family: Montserrat, sans-serif; font-size: 2rem; font-weight: 600;
  color: #fff; letter-spacing: -.03em; text-transform: none; margin-bottom: .15rem;
}

/* -------------------------------------------------------------- servicios */
/* La imagen deja de vivir en una caja redondeada y pasa a ser el fondo de toda
   la seccion. El velo en dos capas mantiene legible el texto a la derecha y las
   tarjetas de abajo sin apagar del todo la foto. */
/* Sin foto de fondo: la seccion se sostiene con tipografia y espacio. */
/* El banner ya no necesita imagen ni caja propias: queda solo el copy. */
.tst-public-home .services-editorial-banner {
  background: none !important; min-height: 0 !important; border-radius: 0 !important;
  padding: 0 !important; margin-bottom: 3.5rem !important;
  display: block !important; overflow: visible !important;
}
.tst-public-home .services-editorial-banner::after { display: none !important; }
.tst-public-home .services-editorial-copy { max-width: 640px; margin-left: auto; text-align: left; }
.tst-public-home .services-editorial-copy h2 { font-size: clamp(2.1rem, 4vw, 3.5rem); }

/* Tarjetas de vidrio: se apoyan sobre la foto sin taparla. */
.tst-public-home .servicio-mini {
  background: #0a251e73 !important;
  border: 1px solid #ffffff1f !important; border-radius: 6px;
  transition: border-color .3s ease, transform .3s ease, background-color .3s ease;
}
.tst-public-home .servicio-mini:hover {
  border-color: #a8ebd085 !important; background: #0a251eb0 !important; transform: translateY(-4px);
}

/* --------------------------------------------------------------- campanas */
/* Antes: titular de 2.8rem en peso 800 centrado, la bajada descuadrada y las
   miniaturas cortadas contra el borde de la ventana. */
.tst-public-home #campanas { background-color: var(--home-section-bg) !important; }
.tst-public-home .campanas-header {
  text-align: left !important;
  padding: 0 max(1.25rem, calc((100vw - 1280px) / 2)) 2.5rem !important;
  display: grid; gap: .1rem;
}
.tst-public-home .campanas-header h2 {
  font-weight: 600 !important; letter-spacing: -.04em; line-height: 1.1;
  font-size: clamp(2rem, 4vw, 3.25rem) !important; margin: 0 0 .5rem;
}
.tst-public-home .campanas-header h2 span { color: #a8ebd0; }
.tst-public-home .campanas-header p {
  margin-inline: 0 !important; max-width: 56ch; font-size: .98rem; color: #ffffffb8;
}
.tst-public-home .campanas-header .editorial-eyebrow { margin-bottom: .9rem; }
.tst-public-home .campanas-row {
  padding-block: 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
}
.tst-public-home .campanas-track { gap: 1rem; }
.tst-public-home .campanas-item {
  width: 260px; height: 260px; border-radius: 4px;
  border: 1px solid #ffffff1f; box-shadow: none;
  transition: transform .45s cubic-bezier(.2,.8,.2,1), border-color .3s ease;
}
.tst-public-home .campanas-item:hover {
  transform: translateY(-6px); border-color: #a8ebd08a; box-shadow: none;
}

/* --------------------------------------------------- reconocimientos + faq */
.tst-public-home #reconocimientos .section-header p { margin-inline: 0; max-width: 56ch; }
.tst-public-home .reconocimiento-item {
  border-radius: 4px !important; border-color: #ffffff26 !important;
  transition: border-color .3s ease;
}
.tst-public-home .reconocimiento-item:hover { border-color: #a8ebd08a !important; }

.tst-public-home .faq-container { grid-template-columns: .8fr 1.2fr; gap: 4.5rem; }
.tst-public-home .faq-left h2 {
  font-weight: 600 !important; font-size: clamp(2rem, 3.5vw, 3.25rem);
  letter-spacing: -.04em; line-height: 1.1;
}
.tst-public-home .faq-left h2 span { color: #a8ebd0; }
.tst-public-home .faq-left .section-label {
  display: inline-block; background: none !important; border: 0 !important; padding: 0 !important;
  border-radius: 0 !important; font-size: .72rem; font-weight: 600;
  letter-spacing: .2em; color: #bde9dc;
}
.tst-public-home .faq-item { border-color: #ffffff1f !important; }
.tst-public-home .faq-question { padding-block: 1.5rem; letter-spacing: -.01em; }

/* Numeracion: da ritmo a la lista y la hace escaneable. */
.tst-public-home .faq-right { counter-reset: faq; }
.tst-public-home .faq-item { counter-increment: faq; }
.tst-public-home .faq-question > span:first-child::before {
  content: counter(faq, decimal-leading-zero);
  display: inline-block; min-width: 2.75rem;
  font-size: .72rem; font-weight: 600; letter-spacing: .12em; color: #7fd3bb;
}

/* --------------------------------------------------------------- contacto */
/* Reparto asimetrico: el discurso a la izquierda, el formulario a la derecha.
   El grid se aplica a la propia seccion, asi que no hace falta tocar el HTML. */
.tst-public-home #contacto {
  display: grid; grid-template-columns: .85fr 1.15fr;
  gap: clamp(2.5rem, 5vw, 5rem); align-items: start;
}
.tst-public-home #contacto .section-header {
  text-align: left; margin-bottom: 0; position: sticky; top: 6.5rem;
}
.tst-public-home #contacto .section-header p { margin-inline: 0; max-width: 42ch; }
.tst-public-home .contact-explainer { font-size: .9rem; color: #ffffff9e; margin-top: 1rem; }
.tst-public-home .contact-form-container {
  background: none !important; border: 0 !important; box-shadow: none !important;
  padding: 0 !important; max-width: none; margin: 0;
}

/* Campos con filete inferior en vez de cajas: menos ruido, mas editorial. */
.tst-public-home #contacto .form-group { margin-bottom: 1.75rem; }
.tst-public-home #contacto label {
  display: block; font-size: .72rem; letter-spacing: .14em; text-transform: uppercase;
  color: #a9d9cb; margin-bottom: .6rem;
}
.tst-public-home #contacto .form-control {
  background: transparent !important; border: 0 !important;
  border-bottom: 1px solid #ffffff33 !important; border-radius: 0 !important;
  padding: .7rem 0 !important; color: #fff !important; font-size: 1rem;
  transition: border-color .3s ease;
}
.tst-public-home #contacto .form-control::placeholder { color: #ffffff54; }
.tst-public-home #contacto .form-control:focus {
  outline: none; border-bottom-color: #a8ebd0 !important; box-shadow: none !important;
}
.tst-public-home #contacto textarea.form-control { resize: vertical; min-height: 120px; }
.tst-public-home #contacto .form-btn {
  border-radius: 999px; padding: 1rem 2.25rem; font-size: .9rem;
  letter-spacing: .04em; min-height: 52px;
}

@media (max-width: 900px) {
  .tst-public-home .faq-container { grid-template-columns: 1fr; gap: 2.5rem; }
  .tst-public-home #contacto { grid-template-columns: 1fr; }
  .tst-public-home #contacto .section-header { position: static; }
  .tst-public-home .services-editorial-copy { margin-left: 0; }
  .tst-public-home .campanas-item { width: 200px; height: 200px; }
  .tst-public-home .clients-track { gap: 2rem; }
  .tst-public-home .clients-track .client-logo { width: 150px; }
  .tst-public-home .clients-track .client-logo img { max-height: 54px; }
  .clients-meta { gap: 1.75rem; }
  .clients-meta b { font-size: 1.6rem; }
}

/* Rejilla de servicios: 12 tarjetas de alto identico.
   Los textos son de largos muy distintos (una tarjeta trae ademas un <details>),
   asi que sin esto cada fila quedaba escalonada. grid-auto-rows:1fr iguala las
   filas y el flex interno empuja las fichas al pie de cada tarjeta. */
.tst-public-home .services-mini-grid { grid-auto-rows: 1fr; align-items: stretch; }
.tst-public-home .servicio-mini {
  height: 100%; display: flex; flex-direction: column; align-items: flex-start;
}
.tst-public-home .servicio-mini > p { flex: 1 1 auto; }
.tst-public-home .servicio-mini .sm-chips { margin-top: auto; padding-top: 1rem; }
.tst-public-home .servicio-mini .service-details { width: 100%; margin-top: .75rem; }

/* --------------------------------------------------------------------------
   FAQ: acordeon editorial
   La lista ya estaba numerada y con filetes, pero seguia leyendose como un
   formulario: pregunta pequena y un boton circular relleno a la derecha. Aqui
   la fila entera se vuelve el objeto interactivo -- tipografia mas grande, el
   numero como ancla visual, un signo de linea fina que gira al abrir, y un
   desplazamiento sutil al pasar el raton.
   -------------------------------------------------------------------------- */
.tst-public-home .faq-right { border-top: 1px solid #ffffff1f; }
.tst-public-home .faq-item { border-top: 0 !important; border-bottom: 1px solid #ffffff1f !important; }

.tst-public-home .faq-question {
  display: flex; align-items: center; gap: 1.5rem;
  padding: 1.6rem .5rem 1.6rem 0 !important;
  font-size: clamp(.98rem, 1.15vw, 1.1rem); font-weight: 500;
  line-height: 1.35; text-align: left;
  transition: padding-left .35s cubic-bezier(.2,.8,.2,1), color .25s ease;
}
.tst-public-home .faq-question > span:first-child { flex: 1; }
.tst-public-home .faq-question:hover { padding-left: .6rem !important; color: #a8ebd0; }
.tst-public-home .faq-item.open .faq-question { color: #a8ebd0; }

/* El numero deja de ser decoracion y pasa a ser el ancla de la fila. */
.tst-public-home .faq-question > span:first-child::before {
  min-width: 3.25rem; font-size: .78rem; letter-spacing: .14em;
  color: #6fc9af; transition: color .25s ease;
}
.tst-public-home .faq-item.open .faq-question > span:first-child::before,
.tst-public-home .faq-question:hover > span:first-child::before { color: #a8ebd0; }

/* Signo de linea fina en vez de boton relleno: gira 45 grados al abrir. */
.tst-public-home .faq-icon {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%;
  background: none !important; border: 1px solid #ffffff33 !important;
  display: grid; place-items: center; color: #cfeee2;
  transition: transform .4s cubic-bezier(.2,.8,.2,1), border-color .3s ease, background-color .3s ease;
}
.tst-public-home .faq-icon i { font-size: .72rem; }
.tst-public-home .faq-question:hover .faq-icon { border-color: #a8ebd0 !important; }
.tst-public-home .faq-item.open .faq-icon {
  transform: rotate(45deg); border-color: #a8ebd0 !important; background: #a8ebd01f !important;
}

/* La respuesta se alinea con el texto de la pregunta, no con el numero. */
.tst-public-home .faq-answer-inner {
  padding: 0 3.5rem 1.75rem 4.75rem; font-size: .95rem; line-height: 1.75;
  color: #ffffffc4; max-width: 68ch;
}
.tst-public-home .faq-answer-inner strong { color: #a8ebd0; font-weight: 600; }

/* La columna izquierda acompana el scroll de la lista. */
.tst-public-home .faq-left { position: sticky; top: 6.5rem; }
.tst-public-home .faq-lead { max-width: 40ch; }

@media (max-width: 900px) {
  .tst-public-home .faq-left { position: static; }
  .tst-public-home .faq-question { gap: .9rem; font-size: .95rem; }
  .tst-public-home .faq-question > span:first-child::before { min-width: 2.25rem; }
  .tst-public-home .faq-answer-inner { padding: 0 0 1.5rem 2.25rem; }
}

/* --------------------------------------------------------------------------
   Ritmo de la pagina: alternar el lado del bloque de texto
   Videos, FAQ y Contacto caian los tres con el discurso a la izquierda y el
   contenido a la derecha, asi que el ojo bajaba por un unico eje y las tres
   secciones parecian la misma. Se voltea la del medio (FAQ): la lista pasa a
   la izquierda y el titular a la derecha, de modo que el recorrido queda
   izquierda -> derecha -> izquierda.
   -------------------------------------------------------------------------- */
.tst-public-home .faq-container { grid-template-columns: 1.2fr .8fr; }
.tst-public-home .faq-left  { order: 2; }
.tst-public-home .faq-right { order: 1; }

@media (max-width: 900px) {
  /* En una sola columna el titular vuelve arriba: leerlo despues de la lista
     no tendria sentido. */
  .tst-public-home .faq-left  { order: 1; }
  .tst-public-home .faq-right { order: 2; }
}


/* --------------------------------------------------------------------------
   Menu lateral: no repetir lo que ya esta en la cabecera
   Desde 601px la cabecera ya muestra el selector de idioma y "Iniciar sesion",
   asi que dentro del panel eran un duplicado. Por debajo de 600px la cabecera
   oculta el acceso y comprime el idioma a "ES/EN", de modo que ahi si hacen
   falta. "Cotizar Proyecto" se queda siempre: la cabecera nunca lo muestra
   (style.css lo oculta en .nav-actions).
   -------------------------------------------------------------------------- */
@media (min-width: 601px) {
  .tst-public-home .mobile-nav-footer .lang-toggle-mobile,
  .tst-public-home .mobile-nav-footer .nav-login-mobile { display: none !important; }
}

/* --------------------------------------------------------------------------
   Alternancia completa del tramo final
   Con el FAQ ya volteado quedaba: reconocimientos izquierda, video izquierda,
   FAQ derecha, contacto izquierda. Dos bloques seguidos con el texto al mismo
   lado. Volteando tambien reconocimientos el recorrido queda alternado de
   arriba a abajo:

     reconocimientos  texto derecha   (placas a la izquierda)
     TST en accion    texto izquierda (video a la derecha)
     dudas frecuentes texto derecha   (lista a la izquierda)
     contacto         texto izquierda (formulario a la derecha)
   -------------------------------------------------------------------------- */
/* La seccion entera pasa a ser la rejilla: las placas ocupan la columna
   izquierda y, en la derecha, el encabezado queda justo encima del texto que
   introduce. Antes el titulo se quedaba a la izquierda y su propio texto caia
   a la derecha, separados por las placas. */
.tst-public-home #reconocimientos {
  display: grid; grid-template-columns: 1.25fr .75fr;
  grid-template-rows: auto 1fr; gap: 0 clamp(2rem, 4vw, 4rem);
  align-items: start;
}
.tst-public-home #reconocimientos .section-header {
  grid-column: 2; grid-row: 1; margin-bottom: 1.75rem; max-width: none;
}
.tst-public-home .reconocimientos-content { display: contents; }
.tst-public-home .reconocimientos-grid { grid-column: 1; grid-row: 1 / span 2; }
.tst-public-home .reconocimiento-text  { grid-column: 2; grid-row: 2; }

@media (max-width: 900px) {
  /* En una columna: encabezado, texto y luego las placas. */
  .tst-public-home #reconocimientos { display: block; }
  .tst-public-home .reconocimientos-content { display: grid; grid-template-columns: 1fr; gap: 2rem; }
  .tst-public-home .reconocimiento-text  { order: 1; }
  .tst-public-home .reconocimientos-grid { order: 2; }
}

/* Las placas Kommo son fotos de objetos oscuros (promedio RGB ~41,40,40).
   Sobre el fondo verde oscuro de la seccion se leian como rectangulos negros.
   Un lienzo mas claro detras y un realce suave las devuelven a ser objetos. */
.tst-public-home .reconocimiento-item { background: #16403a !important; }
.tst-public-home .reconocimiento-img-wrapper img {
  filter: brightness(1.18) contrast(1.06); border-radius: 2px;
  transition: filter .35s ease, transform .5s cubic-bezier(.2,.8,.2,1);
}
.tst-public-home .reconocimiento-item:hover .reconocimiento-img-wrapper img {
  filter: brightness(1.3) contrast(1.08); transform: scale(1.03);
}

/* --------------------------------------------------------------------------
   Trama de puntos en TODAS las secciones
   El punteado venia de .deco-light/.deco-dark, y solo lo llevaban seis
   secciones: trayectoria, campanas, reconocimientos y videos quedaban planas y
   se notaba el salto al desplazarse. Se aplica el mismo patron a las que no
   tienen esas clases, respetando el tono (blanco sobre verde medio, verde
   sobre verde oscuro) para no duplicar la capa donde ya existe.
   -------------------------------------------------------------------------- */
.tst-public-home > section[data-tone]:not(.deco-light):not(.deco-dark) {
  position: relative; isolation: isolate;
}
.tst-public-home > section[data-tone]:not(.deco-light):not(.deco-dark)::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: radial-gradient(rgba(255, 255, 255, .05) 1px, transparent 1.4px);
  background-size: 30px 30px;
}
.tst-public-home > section[data-tone="dark"]:not(.deco-light):not(.deco-dark)::before {
  background-image: radial-gradient(rgba(0, 212, 170, .07) 1px, transparent 1.4px);
  background-size: 28px 28px;
}

/* En campanas el ::before ya esta ocupado por los degradados laterales
   (style.css .galeria-campanas::before/::after), asi que la trama va como
   background-image de la propia seccion. */
.tst-public-home > section#campanas {
  background-color: var(--home-section-bg) !important;
  background-image: radial-gradient(rgba(255, 255, 255, .05) 1px, transparent 1.4px) !important;
  background-size: 30px 30px !important;
}
.tst-public-home > section#campanas[data-tone="dark"] {
  background-image: radial-gradient(rgba(0, 212, 170, .07) 1px, transparent 1.4px) !important;
  background-size: 28px 28px !important;
}

/* Emojis del menu lateral publico: misma metrica que .admin-nav-icon del
   panel (admin-system.css) para que ambos menus se lean igual. */
.mobile-nav-links .mobile-nav-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; flex: 0 0 22px;
  font: 400 1.1rem/1 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
}

/* ==========================================================================
   Paginas de proyecto: mismo lenguaje editorial que la portada
   --------------------------------------------------------------------------
   Los encabezados seguian con la pildora centrada y el titular en peso 800, y
   en las tarjetas de funcionalidades el numero iba en posicion absoluta con
   2.5rem en peso 900: se montaba encima del texto y lo volvia ilegible. Lo
   mismo el icono, absoluto a la izquierda, que pisaba la primera linea.

   Aqui la tarjeta pasa a ser una rejilla de dos columnas -- indice y texto --
   sin superposiciones, y los encabezados adoptan la receta de la home.
   ========================================================================== */

/* ------------------------------------------------------- encabezados ----- */
.tst-project-page .section-label {
  display: inline-block; background: none !important; border: 0 !important;
  padding: 0 !important; border-radius: 0 !important;
  font-size: .72rem; font-weight: 600; letter-spacing: .2em; text-transform: uppercase;
  color: #bde9dc !important; margin-bottom: 1.25rem;
}
.tst-project-page .section-header { text-align: left; max-width: 62ch; margin-inline: 0; }
.tst-project-page .section-header h2 {
  font-family: Montserrat, sans-serif; font-weight: 600 !important;
  line-height: 1.1; letter-spacing: -.04em; text-wrap: balance;
}
.tst-project-page .section-header p { margin-inline: 0; max-width: 56ch; }

/* ------------------------------------------ tarjetas de funcionalidades -- */
.tst-project-page .pd-features-grid { gap: 1rem; }

.tst-project-page .pd-feature-card {
  display: grid; grid-template-columns: auto 1fr; gap: 1.1rem;
  align-items: start;
  padding: 1.5rem 1.6rem !important;
  border-radius: 6px; border: 1px solid #ffffff1f;
  background: #0a251e73;
  transition: border-color .3s ease, background-color .3s ease, transform .3s cubic-bezier(.2,.8,.2,1);
}
.tst-project-page .pd-feature-card:hover {
  transform: translateY(-4px); border-color: #a8ebd085;
  background: #0a251eb0; box-shadow: none;
}

/* El numero deja de ser una marca de agua detras del texto y pasa a ser el
   indice de la primera columna. */
.tst-project-page .pd-feature-number {
  position: static !important;
  font-size: .72rem !important; font-weight: 600 !important;
  letter-spacing: .12em; color: #7fd3bb !important;
  line-height: 1.6; min-width: 1.75rem;
}

/* El icono sobraba: repetia el mismo tick en cada tarjeta y solo restaba
   espacio al texto. Se conserva en el marcado por si otra vista lo usa. */
.tst-project-page .pd-feature-card .pd-feature-icon { display: none !important; }

.tst-project-page .pd-feature-card h3 {
  margin: 0; font-size: .95rem; font-weight: 500; line-height: 1.5;
  color: #ffffffe0; letter-spacing: -.005em;
}

/* --------------------------------------------------- resto de secciones -- */
.tst-project-page .pd-tech-item,
.tst-project-page .pd-benefit-card {
  border-radius: 6px; border-color: #ffffff1f;
  transition: border-color .3s ease, transform .3s ease;
}
.tst-project-page .pd-tech-item:hover,
.tst-project-page .pd-benefit-card:hover { border-color: #a8ebd085; }

@media (max-width: 600px) {
  .tst-project-page .pd-feature-card { padding: 1.25rem !important; gap: .85rem; }
}

/* El panel ya entra por la izquierda (ver arriba), pero la sombra seguia
   proyectada hacia la izquierda, como cuando entraba desde la derecha. */
.tst-project-page .mobile-nav { left: -100%; right: auto; transition: left .25s ease; visibility: hidden; }
.tst-project-page .mobile-nav.active { left: 0; right: auto; visibility: visible; }
.tst-public-home .mobile-nav.active,
.tst-project-page .mobile-nav.active { box-shadow: 8px 0 40px rgba(0, 0, 0, .18); }

/* Los logotipos cuadrados (Mikfitel, Vorazzo, Injeb, Legion) quedaban mucho
   mas pequenos que los apaisados: con la misma altura maxima ocupan la mitad
   de ancho. Se les da mas altura para igualar la presencia optica. */
.tst-public-home .clients-track .client-logo img[src*="MIKFITEL"],
.tst-public-home .clients-track .client-logo img[src*="VORAZZO"],
.tst-public-home .clients-track .client-logo img[src*="INJEB"],
.tst-public-home .clients-track .client-logo img[src*="LEGION"] {
  max-height: 104px;
}
.tst-public-home .clients-track .client-logo img[src*="COLORS-EARTH"],
.tst-public-home .clients-track .client-logo img[src*="GRAFITEXT"],
.tst-public-home .clients-track .client-logo img[src*="JAYA"],
.tst-public-home .clients-track .client-logo img[src*="MIRACLE"] {
  max-height: 86px;
}
.tst-public-home .clients-marquee { padding-block: 2.75rem; }

/* ==========================================================================
   Paginas de proyecto: alternancia de fondo y de lado
   --------------------------------------------------------------------------
   Los fondos venian asignados a mano seccion por seccion y la secuencia salia
   rota: oscuro, oscuro, claro, oscuro, claro, claro, oscuro. Dos pares
   seguidos del mismo tono hacian que el bloque intermedio pareciera continuar
   el anterior.

   Se resuelve con nth-of-type sobre las <section>, no con reglas por clase:
   algunas secciones son condicionales en project.ejs (el stack tecnologico,
   por ejemplo, solo aparece si el proyecto lo declara), asi que una lista fija
   volveria a descuadrarse en cuanto falte una. Contando hermanos, la
   alternancia se mantiene sea cual sea el proyecto.
   ========================================================================== */

.tst-project-page section {
  position: relative; isolation: isolate;
}
.tst-project-page section:nth-of-type(odd)  { background-color: #0e2e2a !important; }
.tst-project-page section:nth-of-type(even) { background-color: #1f6f63 !important; }

/* La trama de puntos acompana al tono, igual que en la portada. */
.tst-project-page section::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: radial-gradient(rgba(0, 212, 170, .07) 1px, transparent 1.4px);
  background-size: 28px 28px;
}
.tst-project-page section:nth-of-type(even)::before {
  background-image: radial-gradient(rgba(255, 255, 255, .05) 1px, transparent 1.4px);
  background-size: 30px 30px;
}

/* El hero conserva su propia imagen y velo: la trama y el fondo plano lo
   estropearian. */
.tst-project-page .pd-hero { background-color: transparent !important; }
.tst-project-page .pd-hero::before { display: none; }

/* --------------------------------------------------- alternancia de lado -- */
/* El encabezado cambia de lado a cada seccion, como en la portada, para que el
   ojo no baje siempre por el mismo eje. */
.tst-project-page section:nth-of-type(even) .section-header {
  margin-left: auto; margin-right: 0; text-align: right;
}
.tst-project-page section:nth-of-type(even) .section-header p { margin-left: auto; margin-right: 0; }

@media (max-width: 900px) {
  /* En pantallas estrechas el texto alineado a la derecha se lee peor: todo
     vuelve a la izquierda. */
  .tst-project-page section:nth-of-type(even) .section-header {
    margin-left: 0; text-align: left;
  }
  .tst-project-page section:nth-of-type(even) .section-header p { margin-left: 0; }
}

/* .gradient-text pinta el texto con un degradado de #1F6F63 a #3FAE9A, que es
   justo el verde de las secciones claras: la palabra acentuada del titular
   quedaba practicamente invisible sobre ellas y apagada sobre las oscuras.
   style.css ya lo corrige para .deco-light y algunas secciones del home, pero
   las paginas de proyecto no llevan esas clases. Se usa el acento de marca
   sobre fondo oscuro y blanco sobre el claro, como en la portada. */
.tst-project-page .gradient-text,
.tst-project-page .section-header h2 span {
  background: none !important;
  -webkit-text-fill-color: #a8ebd0 !important;
  color: #a8ebd0 !important;
}
.tst-project-page section:nth-of-type(even) .gradient-text,
.tst-project-page section:nth-of-type(even) .section-header h2 span {
  -webkit-text-fill-color: #ffffff !important;
  color: #ffffff !important;
}

/* ==========================================================================
   Hero y cierre de las paginas de proyecto
   --------------------------------------------------------------------------
   El hero seguia con el lenguaje anterior: pastillas de colores para la
   tecnologia, titular en peso 800 y dos botones rellenos del mismo peso
   visual, de modo que ninguno destacaba. El cierre repetia el patron centrado
   con dos botones iguales.

   Se traslada la receta del hero de la portada: antetitulo diminuto, titular
   grande de peso medio con tracking negativo, texto de anchura controlada y
   una sola accion solida acompanada de un enlace de texto con flecha.
   ========================================================================== */

/* ------------------------------------------------------------- distintivos */
/* Las pastillas de color pasan a etiquetas de contorno fino. El color propio
   de cada tecnologia se conserva en el borde y el icono, no en el relleno. */
.tst-project-page .pd-tech-badge {
  background: none !important;
  border: 1px solid #ffffff2e !important;
  color: #dff3ea !important;
  border-radius: 999px; padding: .4rem .9rem;
  font-size: .68rem !important; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
}
.tst-project-page .pd-tech-badge i { color: var(--color, #a8ebd0) !important; font-size: .7rem; }
.tst-project-page .pd-hero-badges { gap: .5rem; margin-bottom: 1.75rem; }

/* ---------------------------------------------------------------- titular */
.tst-project-page .pd-title {
  font-family: Montserrat, sans-serif;
  font-weight: 600 !important;
  font-size: clamp(2.4rem, 5vw, 4.25rem) !important;
  line-height: 1.02; letter-spacing: -.045em;
  margin: 0 0 .75rem; text-wrap: balance;
}
.tst-project-page .pd-subtitle {
  font-size: 1.05rem !important; font-weight: 400;
  color: #a8ebd0 !important; letter-spacing: -.01em; margin: 0;
}
/* El filete corto bajo el subtitulo se alarga y se afina: pasa de adorno a
   separador, como los que usa la portada. */
.tst-project-page .pd-divider {
  width: 100% !important; max-width: 520px; height: 1px !important;
  background: #ffffff26 !important; margin: 2rem 0 1.75rem !important;
}
.tst-project-page .pd-desc {
  font-size: .98rem; line-height: 1.75; color: #ffffffc4;
  max-width: 58ch;
}

/* ---------------------------------------------------------------- acciones */
/* Una accion solida y el resto como enlaces de texto: con dos botones rellenos
   el ojo no sabia cual era el paso principal. */
.tst-project-page .pd-actions { gap: 1.5rem; align-items: center; margin-top: 2.25rem; }
.tst-project-page .pd-actions .btn-primary {
  border-radius: 999px; padding: .95rem 1.9rem; min-height: 52px;
  font-weight: 600; letter-spacing: .01em;
}
.tst-project-page .pd-actions .btn-primary ~ .btn-primary,
.tst-project-page .pd-actions .btn-secondary {
  background: none !important; box-shadow: none !important;
  border: 0 !important; border-bottom: 1px solid #ffffff65 !important;
  border-radius: 0 !important; padding: .35rem 0 !important;
  color: #fff !important; font-weight: 500; min-height: 44px;
}
.tst-project-page .pd-actions .btn-primary ~ .btn-primary:hover,
.tst-project-page .pd-actions .btn-secondary:hover {
  color: #8ff3d9 !important; border-bottom-color: #8ff3d9 !important;
  transform: none !important;
}

/* ------------------------------------------------------------ cierre (CTA) */
.tst-project-page .pd-cta-content {
  text-align: left; max-width: 1280px; margin-inline: auto;
}
.tst-project-page .pd-cta-content h2 {
  font-family: Montserrat, sans-serif; font-weight: 600 !important;
  font-size: clamp(2rem, 3.5vw, 3.25rem); line-height: 1.1;
  letter-spacing: -.04em; margin-bottom: .75rem;
}
.tst-project-page .pd-cta-content > p {
  font-size: 1rem; color: #ffffffc4; max-width: 52ch; margin-inline: 0;
}
.tst-project-page .pd-cta-buttons {
  justify-content: flex-start; gap: 1.75rem; align-items: center; margin-top: 2rem;
}
.tst-project-page .pd-cta-buttons .btn-lg {
  border-radius: 999px; padding: 1rem 2.1rem; min-height: 52px;
  font-weight: 600; letter-spacing: .01em;
}
.tst-project-page .pd-cta-buttons .btn-secondary {
  background: none !important; border: 0 !important;
  border-bottom: 1px solid #ffffff65 !important; border-radius: 0 !important;
  padding: .35rem 0 !important; color: #fff !important; min-height: 44px;
}
.tst-project-page .pd-cta-buttons .btn-secondary:hover {
  color: #8ff3d9 !important; border-bottom-color: #8ff3d9 !important;
}

/* La miga de pan tambien en clave editorial. */
.tst-project-page .pd-breadcrumb {
  font-size: .72rem; letter-spacing: .14em; text-transform: uppercase;
  color: #a9d9cb;
}
.tst-project-page .pd-breadcrumb a { color: #a8ebd0; text-decoration: none; }

@media (max-width: 900px) {
  .tst-project-page .pd-actions,
  .tst-project-page .pd-cta-buttons { gap: 1.1rem; }
  .tst-project-page .pd-divider { max-width: none; }
}

/* --------------------------------------------------------------------------
   El cierre y el pie deben leerse como un solo bloque
   El color de fondo ya coincidia (#0e2e2a en ambos), pero la costura se veia
   igual por dos motivos: la trama del cierre era verde (rgba(0,212,170,.07))
   mientras la del pie es blanca (rgba(255,255,255,.05)), y encima .pd-cta-bg
   sumaba un halo verde desplazado que tenia la mitad superior.

   En la portada esto no pasaba porque #contacto lleva .deco-light, cuya trama
   ya es la blanca del pie. Aqui se replica esa condicion.
   -------------------------------------------------------------------------- */
.tst-project-page .pd-cta::before {
  background-image: radial-gradient(rgba(255, 255, 255, .05) 1px, transparent 1.4px) !important;
  background-size: 30px 30px !important;
}
.tst-project-page .pd-cta-bg { display: none !important; }

/* Sin filete ni sombra entre el cierre y el pie: cualquier linea ahi delata la
   union de dos bloques que deben leerse como uno. */
.tst-project-page .pd-cta { border-bottom: 0 !important; box-shadow: none !important; }
.tst-project-page .pd-cta + footer,
.tst-public-home #contacto + footer { border-top: 0 !important; }

/* ==========================================================================
   Stack tecnologico: lista editorial en vez de tarjetas con barra
   --------------------------------------------------------------------------
   El diseno anterior metia cada tecnologia en una tarjeta con fondo, borde
   redondeado y una barra gruesa de 8px rellena con el degradado de marca. Dos
   problemas: sobre las secciones de tono claro el degradado era casi el color
   del fondo y la barra desaparecia, y el conjunto pesaba mucho para lo que
   comunica -- cinco tarjetas apiladas solo para decir cinco porcentajes.

   Ahora es una lista: nada de cajas, filas separadas por filete, el nombre en
   versalitas con tracking y el porcentaje como cifra grande de peso ligero.
   La barra baja a 2px y hace de subrayado de la fila, no de protagonista.
   ========================================================================== */

.tst-project-page .pd-tech-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 clamp(2rem, 5vw, 5rem); max-width: 1280px;
}

.tst-project-page .pd-tech-card {
  background: none !important; border: 0 !important;
  border-top: 1px solid #ffffff1f !important;
  border-radius: 0 !important; padding: 1.35rem 0 1.1rem !important;
  transition: padding-left .35s cubic-bezier(.2, .8, .2, 1);
}
/* Las dos ultimas filas cierran la lista por abajo. */
.tst-project-page .pd-tech-card:nth-last-child(-n+2) { border-bottom: 1px solid #ffffff1f !important; }
.tst-project-page .pd-tech-card:hover {
  background: none !important; transform: none !important;
  border-color: #a8ebd08a !important; padding-left: .6rem !important;
}

.tst-project-page .pd-tech-header { align-items: baseline; margin-bottom: .85rem !important; }

.tst-project-page .pd-tech-name {
  font-size: .78rem !important; font-weight: 600 !important;
  letter-spacing: .16em; text-transform: uppercase;
  color: #ffffffbf !important; transition: color .3s ease;
}
.tst-project-page .pd-tech-card:hover .pd-tech-name { color: #fff !important; }

/* La cifra manda: grande, de peso ligero y con el simbolo discreto. */
.tst-project-page .pd-tech-percent {
  font-family: Montserrat, sans-serif;
  font-size: 1.75rem !important; font-weight: 400 !important;
  letter-spacing: -.04em; color: #fff !important;
  font-variant-numeric: tabular-nums;
}

/* Filete de 2px: subraya la fila, no compite con ella. */
.tst-project-page .pd-tech-bar {
  height: 2px !important; border-radius: 0 !important;
  background: #ffffff1f !important; overflow: visible !important;
}
.tst-project-page .pd-tech-fill {
  height: 2px !important; border-radius: 0 !important;
  background: #a8ebd0 !important;
}
/* Sin el destello del extremo: sobre un filete de 2px solo emborronaba. */
.tst-project-page .pd-tech-fill::after { display: none !important; }

/* En las secciones de tono claro el acento pierde fuerza: se usa blanco, que
   es lo que contrasta sobre el verde medio. */
.tst-project-page section:nth-of-type(even) .pd-tech-bar { background: #0a251e33 !important; }
.tst-project-page section:nth-of-type(even) .pd-tech-fill { background: #ffffff !important; }

@media (max-width: 760px) {
  .tst-project-page .pd-tech-grid { grid-template-columns: 1fr; }
  .tst-project-page .pd-tech-card:nth-last-child(-n+2) { border-bottom: 0 !important; }
  .tst-project-page .pd-tech-card:last-child { border-bottom: 1px solid #ffffff1f !important; }
  .tst-project-page .pd-tech-percent { font-size: 1.5rem !important; }
}

/* ==========================================================================
   Pantalla de carga
   --------------------------------------------------------------------------
   La anterior venia de otra epoca del sitio: degradado azul grisaceo
   (#0d1b2a -> #2d3a4a) que no es ningun color de la marca, logotipo latiendo,
   veinte particulas flotando, el nombre apareciendo letra a letra y cinco
   segundos fijos de espera aunque la pagina ya estuviera lista.

   Se rehace con el mismo lenguaje que el resto: verde de marca, trama de
   puntos, logotipo en blanco, nombre con tracking amplio y un filete que se
   llena. Y sobre todo, se va cuando la pagina esta lista, no cuando vence un
   contador.
   ========================================================================== */

.splash-screen {
  background: #0a251e !important;
  background-image: radial-gradient(rgba(255, 255, 255, .05) 1px, transparent 1.4px) !important;
  background-size: 30px 30px !important;
  gap: 0 !important;
  transition: opacity .55s ease, visibility .55s ease !important;
}

/* El logotipo verde sobre fondo oscuro se pasa a blanco con el mismo filtro
   que usa la cabecera; sin latido: la espera ya se comunica con el filete. */
.splash-logo img {
  width: 84px !important; height: 84px !important;
  filter: brightness(0) invert(1);
  animation: none !important;
  opacity: 0; transform: translateY(10px);
  animation: splashEntra .7s cubic-bezier(.2, .8, .2, 1) forwards !important;
}

/* El nombre entra como bloque, no letra a letra: el efecto maquina de escribir
   obligaba a esperar a que terminara de escribirse. */
.splash-text {
  font-family: Montserrat, sans-serif !important;
  font-size: clamp(1.1rem, 2.4vw, 1.6rem) !important;
  font-weight: 600 !important;
  letter-spacing: .38em !important;
  color: #fff !important;
  margin: 1.75rem 0 .5rem !important;
  opacity: 0;
  animation: splashEntra .7s .12s cubic-bezier(.2, .8, .2, 1) forwards !important;
}
.splash-text span {
  animation: none !important; opacity: 1 !important; transform: none !important;
}

.splash-tagline {
  margin-top: .35rem !important;
  animation-delay: .22s !important;
  font-size: .62rem !important; letter-spacing: .3em !important;
  font-weight: 600 !important; color: #a8ebd0 !important;
  text-transform: uppercase; opacity: 0;
  animation: splashEntra .7s .22s cubic-bezier(.2, .8, .2, 1) forwards !important;
}

/* El disco giratorio se sustituye por un filete que avanza: ocupa poco y
   comunica progreso en vez de espera indefinida. */
.splash-spinner {
  /* El original era un disco absoluto anclado a 60px del borde inferior; aqui
     vuelve al flujo para quedar bajo el lema, a la misma anchura del bloque. */
  /* 'relative' para poder colocar el relleno dentro, pero anulando el
     desplazamiento: el original era absoluto con bottom:60px y, al volver al
     flujo, ese desplazamiento lo subia justo encima del lema. */
  position: relative !important;
  bottom: auto !important; top: auto !important; left: auto !important; right: auto !important;
  width: min(220px, 42vw) !important; height: 1px !important;
  border: 0 !important; border-radius: 0 !important;
  background: #ffffff26 !important;
  margin: 2.75rem 0 0 !important;
  animation: none !important;
  overflow: hidden;
}
.splash-spinner::after {
  content: ''; position: absolute; inset: 0;
  background: #a8ebd0; transform-origin: left;
  transform: scaleX(0);
  animation: splashBarra 1.1s cubic-bezier(.4, 0, .2, 1) forwards;
}

/* Las particulas sobraban: veinte nodos animados solo para rellenar. */
.splash-particles { display: none !important; }

@keyframes splashEntra {
  to { opacity: 1; transform: none; }
}
@keyframes splashBarra {
  0%   { transform: scaleX(0); }
  70%  { transform: scaleX(.75); }
  100% { transform: scaleX(1); }
}

/* Quien pide menos movimiento ve la pantalla estatica y breve. */
@media (prefers-reduced-motion: reduce) {
  .splash-logo img, .splash-text, .splash-tagline {
    animation: none !important; opacity: 1 !important; transform: none !important;
  }
  .splash-spinner::after { animation: none !important; transform: scaleX(1); }
}


/* ==========================================================================
   Equipo + resena en Google
   --------------------------------------------------------------------------
   Las tarjetas NFC de cada uno viven en subdominios sueltos (esteban / isaac /
   nicolas) y no habia forma de llegar a ellas desde la portada: quien recibia
   una tarjeta fisica entraba, pero desde la web no existian.

   Se resuelven las dos cosas en una sola seccion al cierre: la lista del
   equipo y la peticion de resena. Va despues de contacto, de modo que la
   alternancia de tonos sigue intacta (contacto oscuro -> equipo claro -> pie
   oscuro) y el lado del texto se invierte respecto a contacto: alli el
   discurso va a la izquierda, aqui a la derecha.
   ========================================================================== */

.tst-public-home #equipo {
  display: grid;
  grid-template-columns: 1.15fr .85fr;
  grid-template-rows: auto auto;
  gap: 0 clamp(2rem, 4vw, 4.5rem);
  align-items: start;
}
.tst-public-home #equipo .section-header {
  grid-column: 2; grid-row: 1; max-width: none; margin-bottom: 0;
}
.tst-public-home #equipo .section-header h2 span { color: #a8ebd0; }

/* ------------------------------------------------------------ lista equipo */
/* Lista con filetes en vez de tarjetas: son tres personas, no tres productos.
   El numero da ritmo, igual que la numeracion del acordeon de dudas. */
.tst-public-home .team-grid {
  grid-column: 1; grid-row: 1;
  border-top: 1px solid #ffffff1f;
}
.tst-public-home .team-card {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: clamp(1rem, 2vw, 2.25rem);
  padding: 1.5rem .25rem;
  border-bottom: 1px solid #ffffff1f;
  text-decoration: none; color: #fff;
  min-height: 44px;
  transition: background-color .3s ease, padding-left .3s cubic-bezier(.2, .8, .2, 1);
}
.tst-public-home .team-card:hover,
.tst-public-home .team-card:focus-visible {
  background: #ffffff0f; padding-left: 1rem; outline: none;
}
.tst-public-home .team-card-index {
  font-size: .72rem; font-weight: 600; letter-spacing: .12em; color: #7fd3bb;
  min-width: 2rem;
}
.tst-public-home .team-card-body { display: grid; gap: .2rem; min-width: 0; }
.tst-public-home .team-card-body strong {
  font-family: Montserrat, sans-serif; font-weight: 600;
  font-size: clamp(1.05rem, 1.7vw, 1.35rem); letter-spacing: -.02em;
}
.tst-public-home .team-card-role {
  font-size: .78rem; letter-spacing: .12em; text-transform: uppercase;
  color: #bde9dc;
}
.tst-public-home .team-card-link {
  font-size: .78rem; font-weight: 600; color: #a8ebd0;
  display: inline-flex; align-items: center; gap: .55rem; white-space: nowrap;
}
.tst-public-home .team-card-link i { transition: transform .3s cubic-bezier(.2, .8, .2, 1); }
.tst-public-home .team-card:hover .team-card-link i { transform: translate(3px, -3px); }

/* --------------------------------------------------------- banda de resena */
/* Placa oscura dentro de la seccion clara: la peticion de resena es la unica
   accion de la pagina dirigida a quien ya es cliente, y necesita separarse de
   lo demas sin inventar otro color fuera de la paleta. */
.tst-public-home .review-band {
  grid-column: 1 / -1; grid-row: 2;
  margin-top: clamp(2.5rem, 5vw, 4rem);
  display: grid; grid-template-columns: 1.2fr auto;
  align-items: center; gap: clamp(1.5rem, 4vw, 3.5rem);
  padding: clamp(1.75rem, 3.5vw, 2.75rem);
  background-color: #0e2e2a;
  background-image: radial-gradient(rgba(0, 212, 170, .07) 1px, transparent 1.4px);
  background-size: 28px 28px;
  background-attachment: fixed;
  border: 1px solid #ffffff1f; border-radius: 4px;
}
.tst-public-home .review-band h3 {
  font-family: Montserrat, sans-serif; font-weight: 600;
  font-size: clamp(1.5rem, 2.6vw, 2.25rem); line-height: 1.15;
  letter-spacing: -.035em; color: #fff; margin: 0 0 .6rem;
}
.tst-public-home .review-band p {
  margin: 0; font-size: .95rem; line-height: 1.7;
  color: #ffffffc4; max-width: 52ch;
}
.tst-public-home .review-band-action {
  display: grid; justify-items: end; gap: .9rem;
}
.tst-public-home .review-stars {
  display: inline-flex; gap: .3rem; color: #fbbc04; font-size: .95rem;
}
/* Boton solido en el acento de marca: sobre la placa oscura el degradado
   verde se confundia con el fondo de la seccion. */
.tst-public-home .review-band .btn-primary {
  background: #a8ebd0 !important; color: #0e2e2a !important;
  box-shadow: none !important; border-radius: 999px;
  padding: .95rem 1.9rem; min-height: 52px; font-weight: 600;
  white-space: nowrap;
}
.tst-public-home .review-band .btn-primary:hover {
  background: #c6f4e2 !important; transform: translateY(-2px);
}
.tst-public-home .review-band .btn-primary i { font-size: 1rem; }

@media (max-width: 900px) {
  .tst-public-home #equipo { display: block; }
  .tst-public-home #equipo .section-header { margin-bottom: 2rem; }
  .tst-public-home .review-band {
    grid-template-columns: 1fr; margin-top: 2.5rem;
    background-attachment: scroll;
  }
  .tst-public-home .review-band-action { justify-items: start; }
  .tst-public-home .review-band .btn-primary { width: 100%; justify-content: center; }
}
@media (max-width: 560px) {
  .tst-public-home .team-card {
    grid-template-columns: auto 1fr; gap: .75rem 1rem; padding-block: 1.25rem;
  }
  .tst-public-home .team-card-link { grid-column: 2; }
  .tst-public-home .team-card:hover { padding-left: .25rem; }
}


/* ==========================================================================
   Fondos fotograficos de seccion
   --------------------------------------------------------------------------
   Solo la portada tenia imagen (hero-infrastructure.jpg) y el resto eran
   planchas de color: servicios, dudas frecuentes y equipo se leian como tres
   bloques iguales seguidos.

   Se aplica la misma receta del hero (imagen + velo de color por encima), con
   una diferencia importante: aqui el velo tambien lleva la trama de puntos.
   La trama de estas secciones vive en `.deco-light::before` / `.deco-dark::before`
   (style.css) y en el `::before` sin clase deco (mas arriba en esta hoja), y
   ninguno de los dos lleva z-index, asi que la fotografia los tapaba. Pintarla
   sobre el velo es lo que la devuelve, y ademas queda por delante de la foto,
   que es donde debe estar.

   Las tres imagenes son de Pexels, licencia libre para uso comercial y sin
   atribucion: 9300768 (oficina contemporanea), 8867405 (equipo de soporte) y
   6804068 (equipo de desarrollo).
   ========================================================================== */

.tst-public-home :is(#servicios, #faq, #equipo) {
  position: relative; isolation: isolate; overflow: hidden;
}
/* El contenido va por encima de las dos capas. `.deco-light > *` ya pone
   z-index 1 a los hijos directos, pero #linea-tiempo y #equipo no llevan
   clase deco. */
.tst-public-home :is(#servicios, #faq, #equipo) > *:not(.section-bg):not(.section-shade) {
  position: relative; z-index: 1;
}
:is(.tst-public-home, .tst-project-page) .section-bg,
:is(.tst-public-home, .tst-project-page) .section-shade {
  position: absolute; inset: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none;
}
/* La imagen NO cubre la seccion entera: estas secciones miden mas de 2000px de
   alto y una foto de 1920x1080 estirada a esa altura se recorta al 43% de su
   ancho, de modo que solo se ve un detalle ampliado al doble. Va como franja
   superior, con su proporcion casi intacta, y el velo la disuelve antes de que
   empiece el contenido denso. */
:is(.tst-public-home, .tst-project-page) .section-bg {
  object-fit: cover; height: clamp(380px, 44vw, 700px); bottom: auto;
  /* La franja se disuelve con mascara sobre la propia imagen, no confiando en
     que el velo llegue a solido justo donde acaba. Con el velo el punto de
     cierre estaba en pixeles y la altura de la franja en vw, asi que a ciertos
     anchos la foto terminaba antes de que el velo cerrase y se veia el corte
     recto. Con la mascara el desvanecido es siempre relativo a la franja. */
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 52%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 0%, #000 52%, transparent 100%);
}
/* La de servicios ocupa toda la seccion; solo se suaviza el ultimo tramo para
   que no choque con el borde inferior. */
.tst-public-home #servicios .section-bg {
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 88%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 0%, #000 88%, transparent 100%);
}

/* ---------------------------------------------------------------- servicios */
/* Tono oscuro y doce tarjetas encima: la foto solo respira en la franja del
   encabezado y se cierra a color solido antes de la rejilla. */
/* Aqui la foto SI cubre la seccion entera, de arriba abajo. El recorte agresivo
   que eso implica no molesta con esta imagen: es un muro de vidrio, un patron
   de montantes verticales que aguanta la ampliacion sin deshacerse. El velo es
   parejo, un poco mas cerrado abajo, donde estan las doce tarjetas. */
.tst-public-home #servicios .section-bg { height: 100%; bottom: 0; object-position: center 45%; }
.tst-public-home #servicios .section-shade {
  background-image:
    radial-gradient(rgba(0, 212, 170, .07) 1px, transparent 1.4px),
    linear-gradient(180deg, color-mix(in srgb, var(--home-section-bg) 62%, transparent) 0%, color-mix(in srgb, var(--home-section-bg) 72%, transparent) 38%, color-mix(in srgb, var(--home-section-bg) 80%, transparent) 100%);
  background-size: 28px 28px, auto;
}
/* Las tarjetas venian al 45% de opacidad, pensadas para un fondo plano: sobre
   la fotografia se transparentaban y el texto se leia sobre el edificio. */
.tst-public-home #servicios .servicio-mini { background: #0a251ed4 !important; }
.tst-public-home #servicios .servicio-mini:hover { background: #0a251eeb !important; }

/* -------------------------------------------------------------------- dudas */
/* Tono claro. El acordeon queda a la izquierda y el titular a la derecha, asi
   que ademas del velo vertical hay uno lateral que pesa mas donde hay mas
   texto pequeno. */
/* La foto anterior era de profundidad de campo corta: el portatil en foco y la
   gente desenfocada a proposito, asi que se veia borrosa por mucho que se
   subiera la resolucion. Esta es nitida, pero tambien mucho mas clara
   (luminancia media 147 frente a 66), y contra texto blanco da solo 3,1 de
   contraste sin velo. Necesita mas velo que la otra: con 0,56-0,66 queda entre
   4,6 y 4,8, por encima del minimo de 4,5, y aun asi se distingue la escena
   porque la imagen es luminosa. El techo son 5,6, que es lo que da el verde de
   la seccion por si solo.

   El degradado vertical ya no vela: solo cierra el pie de la franja. Del
   desvanecido se encarga la mascara de .section-bg. */
.tst-public-home #faq .section-bg { object-position: center 40%; height: clamp(460px, 52vw, 820px); }
.tst-public-home #faq .section-shade {
  background-image:
    radial-gradient(rgba(255, 255, 255, .05) 1px, transparent 1.4px),
    linear-gradient(90deg, color-mix(in srgb, var(--home-section-bg) 66%, transparent) 0%, color-mix(in srgb, var(--home-section-bg) 60%, transparent) 55%, color-mix(in srgb, var(--home-section-bg) 56%, transparent) 100%),
    linear-gradient(180deg, transparent 0%, color-mix(in srgb, var(--home-section-bg) 40%, transparent) 58%, var(--home-section-bg) 100%);
  background-size: 30px 30px, auto, auto;
}

/* ------------------------------------------------------------------- equipo */
/* Igual que dudas: la foto del equipo ya da 5,5 de contraste contra blanco sin
   velo, practicamente el mismo que el verde solo (5,6). Se afloja para que se
   vea gente trabajando y no una mancha. */
.tst-public-home #equipo .section-bg { object-position: center 30%; height: clamp(440px, 50vw, 780px); }
.tst-public-home #equipo .section-shade {
  background-image:
    radial-gradient(rgba(255, 255, 255, .05) 1px, transparent 1.4px),
    linear-gradient(90deg, color-mix(in srgb, var(--home-section-bg) 55%, transparent) 0%, color-mix(in srgb, var(--home-section-bg) 38%, transparent) 55%, color-mix(in srgb, var(--home-section-bg) 20%, transparent) 100%),
    linear-gradient(180deg, color-mix(in srgb, var(--home-section-bg) 30%, transparent) 0%, color-mix(in srgb, var(--home-section-bg) 62%, transparent) 60%, var(--home-section-bg) 100%);
  background-size: 30px 30px, auto, auto;
}

/* En una sola columna el velo lateral ya no protege nada, porque el texto
   ocupa todo el ancho: se sustituye por uno vertical mas cerrado. */
@media (max-width: 900px) {
  :is(.tst-public-home, .tst-project-page) .section-bg { height: clamp(300px, 58vw, 460px); }
  .tst-public-home #faq .section-shade,
  .tst-public-home #equipo .section-shade {
    background-image:
      radial-gradient(rgba(255, 255, 255, .05) 1px, transparent 1.4px),
      linear-gradient(180deg, color-mix(in srgb, var(--home-section-bg) 40%, transparent) 0%, color-mix(in srgb, var(--home-section-bg) 72%, transparent) 60%, var(--home-section-bg) 100%);
    background-size: 30px 30px, auto;
  }
  .tst-public-home #servicios .section-shade {
    background-image:
      radial-gradient(rgba(0, 212, 170, .07) 1px, transparent 1.4px),
      linear-gradient(180deg, color-mix(in srgb, var(--home-section-bg) 79%, transparent) 0%, color-mix(in srgb, var(--home-section-bg) 88%, transparent) 40%, color-mix(in srgb, var(--home-section-bg) 92%, transparent) 100%);
    background-size: 28px 28px, auto;
  }
  /* La de servicios sigue cubriendo toda la seccion tambien en movil. */
  .tst-public-home #servicios .section-bg { height: 100%; }
}

/* ==========================================================================
   Cierre de las paginas de proyecto
   --------------------------------------------------------------------------
   "Necesitas algo similar?" era la unica plancha de color que quedaba en las
   catorce fichas. Lleva la misma receta que la portada, con dos cuidados
   propios de este sitio:

   1. La trama del velo es la BLANCA del pie (rgba(255,255,255,.05) a 30px), no
      la verde de las secciones oscuras. El cierre y el pie tienen que leerse
      como un solo bloque, y una trama distinta delata la union -- es la misma
      razon por la que existe la regla de .pd-cta::before mas arriba.
   2. La franja va arriba y se disuelve antes de llegar al pie, de modo que la
      costura sigue siendo color plano contra color plano.

   Medida la foto, su luminancia media da 5,6 de contraste contra blanco sin
   velo, y el velo oscuro solo lo sube: con 0,40 queda en 8,3. Por eso va tan
   suelta, se ve la escena entera.
   ========================================================================== */
.tst-project-page .pd-cta { isolation: isolate; }
/* La imagen se ata a la altura de la seccion, no a una franja en vw: el cierre
   mide entre 310 y 405px segun el ancho, y una franja de hasta 520px se salia
   por abajo. Con overflow:hidden el sobrante se recorta, de modo que la
   mascara no llegaba a terminar su desvanecido y quedaba un borde de foto a
   medio disolver justo contra el pie -- la costura que se lleva evitando desde
   el principio. Con height:100% la mascara se reparte sobre la seccion entera
   y la foto llega a transparente exactamente en el borde inferior. */
.tst-project-page .pd-cta .section-bg { height: 100%; object-position: center 45%; }
.tst-project-page .pd-cta .section-shade {
  background-image:
    radial-gradient(rgba(255, 255, 255, .05) 1px, transparent 1.4px),
    linear-gradient(180deg, #0e2e2a66 0%, #0e2e2ab3 55%, #0e2e2a 100%);
  background-size: 30px 30px, auto;
}
@media (max-width: 900px) {
  .tst-project-page .pd-cta .section-shade {
    background-image:
      radial-gradient(rgba(255, 255, 255, .05) 1px, transparent 1.4px),
      linear-gradient(180deg, #0e2e2a8c 0%, #0e2e2ac9 50%, #0e2e2a 100%);
    background-size: 30px 30px, auto;
  }
}

/* Tienda oficial: misma retícula y voz editorial de la portada. */
.home-cart-link{display:grid;place-items:center;width:44px;height:44px;border:1px solid #ffffff30;border-radius:50%;color:#fff;text-decoration:none}.home-cart-link:hover{color:#8ff3d9;border-color:#8ff3d9}.home-store-section{overflow:hidden}.home-store-heading{display:flex;align-items:end;justify-content:space-between;gap:2rem;margin-bottom:2rem}.home-store-heading h2{margin:.8rem 0 1rem;color:#fff;font:600 clamp(2rem,3.5vw,3.4rem)/1.08 Montserrat,sans-serif;letter-spacing:-.045em}.home-store-heading h2 span{color:#b6f7df}.home-store-heading p{max-width:55ch;color:#e0f1e9}.home-store-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1.25rem}.home-store-card{overflow:hidden;border:1px solid #ffffff25;border-radius:12px;background:#123d36}.home-store-image{position:relative;display:grid;place-items:center;aspect-ratio:16/10;overflow:hidden;color:#fff;background:linear-gradient(145deg,#0e2e2a,#2f8879)}.home-store-image img{width:100%;height:100%;object-fit:cover}.home-store-image>span{display:grid;place-items:center;width:76px;aspect-ratio:1;border:2px solid #ffffffb5;border-radius:18px;font:800 1.1rem Montserrat,sans-serif}.home-store-image small{position:absolute;top:1rem;left:1rem;padding:.3rem .6rem;border:1px solid #ffffff40;border-radius:999px;background:#0e2e2a99;text-transform:uppercase}.home-store-card>div{display:grid;grid-template-columns:1fr auto;gap:.45rem 1rem;padding:1.2rem}.home-store-card p{grid-column:1/-1;margin:0;color:#9ed9c8;font:700 .68rem ui-monospace,monospace}.home-store-card h3{grid-column:1/-1;margin:0 0 .5rem;color:#fff;font:700 1.1rem Montserrat,sans-serif}.home-store-card h3 a{color:inherit;text-decoration:none}.home-store-price{color:#fff;font:800 1.2rem Montserrat,sans-serif}.home-store-stock{justify-self:end;color:#a8ebd0;font-size:.75rem}.home-store-link{grid-column:1/-1;display:flex;justify-content:space-between;align-items:center;min-height:44px;margin-top:.7rem;padding-top:.8rem;border-top:1px solid #ffffff20;color:#d9f5ea;text-decoration:none;font-size:.84rem}.home-store-empty,.home-store-loading{grid-column:1/-1;display:grid;place-items:center;min-height:250px;padding:2rem;border:1px solid #ffffff25;border-radius:12px;color:#d9eee6;text-align:center;background:#123d36}.home-store-empty h3{margin:.5rem 0;color:#fff;font:600 1.4rem Montserrat,sans-serif}.home-store-empty p{max-width:540px}.home-store-empty>span{font-size:2rem}
@media(max-width:900px){.home-store-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.home-store-card:last-child{display:none}}
@media(max-width:600px){.home-store-heading{display:grid}.home-store-grid{grid-template-columns:1fr}.home-store-card:last-child{display:block}.home-cart-link{width:40px;height:40px}.tst-public-home .editorial-header .nav-actions{gap:.25rem}}
@media (max-width:600px) {
  /* En móvil los dos accesos de bot duplicaban WhatsApp/Telegram y tapaban
     contenido comercial. Conservamos un acceso por canal, más correo. */
  .tst-public-home .floating-contacts .float-btn:nth-child(-n+2) { display:none; }
  .tst-public-home .floating-contacts { right:.55rem; bottom:.65rem; gap:.45rem; animation:none; }
  .tst-public-home .floating-contacts .float-btn { width:44px; height:44px; font-size:1.2rem; }
}

/* Tienda en la home: fotos cuadradas (1:1), igual que en /tienda. */
.home-store-image{aspect-ratio:1/1}

/* Tienda en la home: etiqueta de categoría a la derecha y en verde. */
.home-store-image small{left:auto;right:1rem;z-index:1;border-color:transparent;color:#fff;background:#1f6f63;box-shadow:0 4px 12px rgba(0,0,0,.18)}

/* Tienda en la home: enlace al manual en productos NFC. */
.home-store-manual{grid-column:1/-1;display:inline-flex;align-items:center;gap:.4rem;margin:-.3rem 0 .3rem;color:#8ff3d9;font-size:.8rem;font-weight:700;text-decoration:none}.home-store-manual:hover{text-decoration:underline}

.catalog-tools { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem; margin-bottom: 1.75rem; }
.catalog-search {
  display: flex; align-items: center; gap: .6rem; flex: 1 1 260px; min-height: 46px; padding: 0 1rem;
  border: 1px solid #ffffff2e; border-radius: 999px; background: #ffffff0f; color: #cfeae2;
}
.catalog-search input {
  flex: 1; min-width: 0; border: 0; background: transparent; color: #fff;
  font: 400 .92rem Inter, sans-serif;
}
.catalog-search input::placeholder { color: #9fc2ba; }
.catalog-search input:focus { outline: none; }
.catalog-search:focus-within { border-color: #8ff3d9; }
.catalog-filters { display: flex; flex-wrap: wrap; gap: .5rem; }
.catalog-filters button {
  min-height: 40px; padding: 0 1.05rem; border: 1px solid #ffffff2e; border-radius: 999px;
  background: transparent; color: #d9ebe5; font: 600 .82rem Inter, sans-serif; cursor: pointer;
  transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
.catalog-filters button:hover { border-color: #8ff3d9; color: #8ff3d9; }
.catalog-filters button.active { background: #8ff3d9; border-color: #8ff3d9; color: #04201b; }

.catalog-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.25rem; align-items: stretch; }
.catalog-card {
  display: flex; flex-direction: column; overflow: hidden;
  border: 1px solid #ffffff25; border-radius: 12px; background: #123d36;
}
.catalog-card[hidden] { display: none; }
.catalog-art {
  position: relative; display: grid; place-items: center; aspect-ratio: 16 / 10; overflow: hidden;
  color: #fff; background: linear-gradient(145deg, #0e2e2a, #2f8879); text-decoration: none;
}
.catalog-art img { width: 100%; height: 100%; object-fit: cover; }
.catalog-art-placeholder { display: grid; place-items: center; width: 76px; aspect-ratio: 1; border: 2px solid #ffffffb5; border-radius: 18px; font-size: 1.7rem; }
.catalog-category {
  position: absolute; top: 1rem; left: 1rem; padding: .3rem .65rem; border: 1px solid #ffffff40;
  border-radius: 999px; background: #0e2e2acc; font: 600 .66rem Inter, sans-serif;
  letter-spacing: .06em; text-transform: uppercase;
}
.catalog-promo {
  position: absolute; top: 1rem; right: 1rem; padding: .3rem .65rem; border-radius: 999px;
  background: #ffd166; color: #0e2e2a; font: 800 .7rem Inter, sans-serif;
}
.catalog-card-body { display: flex; flex-direction: column; gap: .35rem; flex: 1; padding: 1.2rem; }
.catalog-sku { margin: 0; color: #9ed9c8; font: 700 .68rem ui-monospace, monospace; }
.catalog-card-body h3 { margin: 0 0 .25rem; color: #fff; font: 700 1.1rem Montserrat, sans-serif; }
.catalog-card-body h3 a { color: inherit; text-decoration: none; }
.catalog-card-body h3 a:hover { color: #8ff3d9; }
.catalog-description {
  margin: 0 0 .5rem; color: #c8e3da; font-size: .86rem; line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.catalog-meta {
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  margin-top: auto; padding-top: .8rem; border-top: 1px solid #ffffff20;
}
.catalog-price { display: flex; align-items: baseline; gap: .45rem; }
.catalog-price del { color: #9fc2ba; font-size: .82rem; }
.catalog-price strong { color: #fff; font: 800 1.25rem Montserrat, sans-serif; }
.catalog-stock { font-size: .75rem; white-space: nowrap; }
.catalog-stock.available { color: #a8ebd0; }
.catalog-stock.empty { color: #f3b0a5; }
.catalog-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin-top: .9rem; }
.catalog-actions .catalog-add { flex: 1 1 auto; justify-content: center; min-height: 46px; }
.catalog-actions .catalog-add[disabled] { opacity: .6; cursor: progress; }
.catalog-detail {
  display: inline-grid; place-items: center; min-height: 46px; padding: 0 1rem;
  border: 1px solid #ffffff2e; border-radius: 999px; color: #d9f5ea; text-decoration: none;
  font: 600 .84rem Inter, sans-serif;
}
.catalog-detail:hover { border-color: #8ff3d9; color: #8ff3d9; }
.catalog-detail-wide { width: 100%; margin-top: .9rem; }
.catalog-action-status { flex: 1 0 100%; min-height: 1.1rem; font-size: .78rem; color: #cfeae2; }
.catalog-action-status.is-ok { color: #8ff3d9; }
.catalog-action-status.is-error { color: #ffc9bf; }
.catalog-no-results { margin: 2rem 0 0; color: #d9eee6; text-align: center; }
.catalog-empty {
  display: grid; place-items: center; gap: .35rem; min-height: 260px; padding: 2.5rem 2rem;
  border: 1px solid #ffffff25; border-radius: 12px; background: #123d36; color: #d9eee6; text-align: center;
}
.catalog-empty > span { font-size: 2rem; color: #8ff3d9; }
.catalog-empty h3 { margin: .5rem 0 0; color: #fff; font: 600 1.45rem Montserrat, sans-serif; }
.catalog-empty p { max-width: 58ch; margin: 0 0 .75rem; }


@media(max-width:900px){.catalog-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:600px){.catalog-grid{grid-template-columns:1fr}}
.catalog-art{aspect-ratio:1/1}
.catalog-category{left:auto;right:1rem;background:#1f6f63;color:#fff;border-color:transparent}
.catalog-promo{right:auto;left:1rem}
/* Categorías bajo cotización: usa el mismo ritmo, color y radios del catálogo. */
.catalog-quote-categories {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .55rem;
    max-width: 1280px;
    margin: 0 auto 1.25rem;
}
.catalog-quote-categories span { color: var(--text-muted, #9db1aa); font-size: .78rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.catalog-quote-categories a { display: inline-flex; align-items: center; min-height: 44px; border: 1px solid rgba(117, 230, 191, .25); border-radius: 999px; color: inherit; font-size: .82rem; padding: .45rem .72rem; text-decoration: none; }
.catalog-quote-categories a:hover,
.catalog-quote-categories a:focus-visible { border-color: var(--primary-color, #3fae9a); color: var(--primary-color, #3fae9a); outline: none; }

/* Featured products: one compact row, native scrolling without JavaScript. */
.home-product-carousel.catalog-grid{--visible-cards:1;--carousel-gap:1rem;display:grid;grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:calc((100% - (var(--visible-cards) - 1)*var(--carousel-gap))/var(--visible-cards));gap:var(--carousel-gap);overflow-x:auto;scroll-snap-type:x mandatory;scroll-padding:0;padding:6px 3px 16px;overscroll-behavior-x:contain;scrollbar-width:thin;scrollbar-color:#b6f7df8c transparent}
/* Barra como la de Proyectos Destacados: sin carril visible, solo el indicador.
   Sobre el teal de la tienda el indicador va en menta claro para que se distinga. */
.tst-public-home .home-showcase::-webkit-scrollbar,.home-product-carousel::-webkit-scrollbar{height:8px}
.tst-public-home .home-showcase::-webkit-scrollbar-track,.home-product-carousel::-webkit-scrollbar-track{background:transparent}
.tst-public-home .home-showcase::-webkit-scrollbar-thumb{background:#3fae9a;border-radius:999px}
.home-product-carousel::-webkit-scrollbar-thumb{background:#b6f7df8c;border-radius:999px}
.home-product-carousel::-webkit-scrollbar-thumb:hover{background:#b6f7dfcc}
.home-product-carousel .catalog-card{min-width:0;scroll-snap-align:start;scroll-margin:3px}
.home-carousel-controls[hidden]{display:none}
.home-product-carousel:focus-visible,.home-store-heading .editorial-text-link:focus-visible{outline:3px solid #b6f7df;outline-offset:3px}
@media(min-width:700px){.home-product-carousel.catalog-grid{--visible-cards:2;--carousel-gap:1.25rem}}
@media(min-width:1100px){.home-product-carousel.catalog-grid{--visible-cards:3}}
@media(min-width:1700px){.home-product-carousel.catalog-grid{--visible-cards:4;--carousel-gap:1.5rem}}
@media(prefers-reduced-motion:reduce){.home-product-carousel{scroll-behavior:auto}}

.home-product-carousel .catalog-art{aspect-ratio:16/10}
.home-product-carousel .catalog-art img{object-fit:contain}

/* Respaldo técnico sin impacto visual: permanece fuera del flujo mientras el
   logotipo carga y solo ocupa su lugar si el recurso falla. */
.tst-public-home .client-logo-fallback {
  max-width: 100%;
  color: #123e34;
  font: 700 .82rem/1.25 Montserrat, sans-serif;
  letter-spacing: .04em;
  text-align: center;
  overflow-wrap: anywhere;
}

/* Servicios: el HTML completo es la degradación sin JS. Al inicializarse, las
   pastillas reducen la vista inicial a cuatro propuestas y permiten recuperar
   las trece mediante “Todos”. */
.service-filter { max-width: 1200px; margin: 0 auto 1.5rem; }
.service-tabs { display: none; flex-wrap: wrap; gap: .65rem; padding: .2rem; }
.service-filter.is-enhanced .service-tabs { display: flex; }
.service-tabs button {
  min-height: 44px;
  border: 1px solid #ffffff35;
  border-radius: 999px;
  padding: .65rem 1rem;
  background: #0a251e9c;
  color: #dff8ef;
  font: 600 .84rem/1 Inter, sans-serif;
  cursor: pointer;
  transition: background-color .16s ease, border-color .16s ease, color .16s ease;
}
.service-tabs button:hover { border-color: #a8ebd0; }
.service-tabs button[aria-selected="true"] { background: #a8ebd0; border-color: #a8ebd0; color: #0a251e; }
.service-tabs button:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }
.service-filter-status { margin: .8rem .25rem 0; color: #c6e8df; font-size: .82rem; }
.services-mini-grid > [hidden] { display: none !important; }
.service-panel-enter { animation: service-panel-enter .16s ease-out; }
@keyframes service-panel-enter { from { opacity: .65; transform: translateY(5px); } }

@media (min-width: 1200px) {
  .tst-public-home .services-mini-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
  /* La ficha ya ofrece un CTA de contacto; la botonera fija tapaba texto y
     controles en 320–390 px, así que se omite solo en proyectos móviles. */
  .tst-project-page .floating-contacts { display: none; }
  .service-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: thin;
    padding: .3rem .15rem .7rem;
  }
  .service-tabs button { flex: 0 0 auto; }
}
@media (prefers-reduced-motion: reduce) {
  .service-panel-enter { animation: none; }
}

/* Fichas de proyecto: el boton de demo usa el mismo azul que el de pagina oficial. */
.tst-public-home .software-card-actions .software-demo-btn {
    background: linear-gradient(135deg, #1a56db 0%, #1e3a8a 100%);
}
.tst-public-home .software-card-actions .software-demo-btn:hover {
    box-shadow: 0 6px 15px rgba(26, 86, 219, 0.35);
}
