/* =========================================================
   STUDIO NOVO — Templates page
   Shared tokens, reset, buttons, header, footer, and the
   scroll-reveal helper now live in common.css (loaded first).
   Only page-specific styles remain below.
   ========================================================= */

/* placeholder blocks (page-specific) */
.ph{ width:100%; height:100%; background: linear-gradient(160deg,#EFEDE6,#E4E0D3); }
.ph--table{ background: linear-gradient(160deg,#2a4433,#0f1f16); min-height: 260px; border-radius: var(--radius-lg); }

/* =========================================================
   Templates hero
   ========================================================= */
.tpl-hero{ padding: 92px 0 20px; text-align:center; }
.tpl-hero__title{ font-size: clamp(2.1rem, 4.6vw, 3rem); line-height:1.15; max-width: 780px; margin: 0 auto; }
.tpl-hero__title em{ font-style:italic; font-weight:600; }

.search{
  max-width: 460px; margin: 44px auto 0;
  display:flex; align-items:center; gap: 12px;
  border-bottom: 1px dashed var(--line);
  padding-bottom: 14px;
}
.search__icon{ width:18px; height:18px; color: var(--ink-faint); flex:0 0 auto; }
.search input{
  flex:1; border:none; background:none; font-family: var(--sans);
  font-size: .95rem; color: var(--ink); outline:none;
}
.search input::placeholder{ color: var(--ink-faint); }

/* =========================================================
   Browse section (filter tabs + cards grid)
   Base desktop padding was missing here — every other page sets
   its own top/bottom padding for its main section (see .price-hero
   + .plans-section, .tw-hero + section{padding} etc). Without it,
   the cards grid butted straight up against the hero above and the
   footer below with zero gap on desktop (only the tablet/mobile
   breakpoints below had padding set).
   ========================================================= */
.tpl-browse{ padding: 72px 0 120px; }

/* =========================================================
   Filter tabs
   — .tabs/.tab base rules now live in common.css (shared with
     the home page); only the deltas stay here.
   ========================================================= */
.tabs{ margin-bottom: 20px; }

.tpl-count{
  text-align:center; font-size:.85rem; color: var(--ink-faint); margin-bottom: 36px;
}

/* =========================================================
   Cards grid
   ========================================================= */
.cards{ display:grid; grid-template-columns: repeat(3,1fr); gap: 26px; }
/* contain:paint reinforces overflow:hidden's clipping for the animated
   (mobile crossfade) images inside — on some mobile browsers, a CSS
   `animation` on an absolutely-positioned child can get promoted to its
   own compositing layer and paint outside an ancestor's overflow:hidden
   bounds; contain:paint forces the browser to clip strictly to this
   box regardless. */
.card{
  background: var(--paper); border:1px solid var(--line); border-radius: var(--radius-lg);
  overflow:hidden; contain: paint; display:flex; flex-direction:column;
  transition: transform .4s var(--ease), box-shadow .4s var(--ease), opacity .3s var(--ease);
}
.card:hover{ transform: translateY(-6px); box-shadow: 0 24px 40px -20px rgba(20,40,29,.16); }
/* min-width:0 overrides the flex item default (min-width:auto), which
   otherwise lets this box's content (the images inside) push it wider
   than the card — the classic cause of an image bleeding past its
   container's edges in a column flex layout. width:100% makes it size
   from its own container explicitly rather than relying on flex-stretch
   alone. contain:paint is the same clipping reinforcement as .card above. */
.card__img{ width:100%; min-width:0; height: 190px; position:relative; overflow:hidden; contain: paint; }
.card__img-default,
.card__img-hover{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; display:block; transition: opacity .35s var(--ease);
}
.card__img-hover{ opacity:0; object-position: top; }
.card:hover .card__img-default{ opacity:0; }
.card:hover .card__img-hover{ opacity:1; }
.card__body{ padding: 18px 20px 22px; display:flex; flex-direction:column; gap:12px; flex:1; }
.card__top{ display:flex; align-items:center; justify-content:space-between; gap:10px; }
.card__top h3{ font-size: 1.05rem; }
.pill{ white-space:nowrap; }
.card__link{
  font-size:.85rem; font-weight:500; color: var(--green); margin-top:auto;
}
.card__link .arrow{ transition: transform .3s var(--ease); display:inline-block; }
.card__link:hover .arrow{ transform: translateX(4px); }

.card.is-hidden{ display:none; }

.tpl-empty{
  display:none; text-align:center; color: var(--ink-faint); font-size:.95rem;
  padding: 60px 20px;
}
.tpl-empty.is-visible{ display:block; }

/* =========================================================
   Responsive — Tablet
   ========================================================= */
@media (max-width: 1024px){
  .cards{ grid-template-columns: repeat(2,1fr); }
  .tpl-hero{ padding-top: 72px; }
  /* .tpl-browse kept its full desktop padding (120px bottom) at tablet —
     every other page tapers its section padding down a step at this
     breakpoint, so this stood out as extra-large. */
  .tpl-browse{ padding: 56px 0 96px; }
}

/* =========================================================
   Responsive — Mobile
   ========================================================= */
@media (max-width: 680px){
  .tpl-hero{ padding: 56px 0 12px; }
  .tabs{ gap: 8px; }
  .tab{ padding: 8px 14px; font-size:.82rem; }

  .tpl-browse{ padding: 48px 0 80px; }
  .cards{ grid-template-columns: 1fr; }
  /* There's no hover on touch, so a card with a second (hover) image
     cross-fades between the two automatically instead — same
     absolute-positioned layering as desktop, just driven by a looping
     animation rather than :hover. Cards with only a default image
     (:not(:has(.card__img-hover))) keep the old static, natural-height
     treatment, since there's nothing to cross-fade with.
     16/9 (not 4/3) — these photos are wide homepage screenshots
     (~16:9-ish). object-fit:cover on a box NARROWER than the source
     (4/3 is much narrower than ~16/9) crops from the left/right, which
     was cutting off the nav bar and logo text on the sides. Desktop's
     fixed 190px-tall box is wide enough that it crops top/bottom
     instead (never an issue) — 16/9 gives mobile the same safe crop
     direction. */
  .card__img:has(.card__img-hover){ width:100%; max-width:100%; height: auto; aspect-ratio: 16 / 9; }
  .card__img:has(.card__img-hover) .card__img-default,
  .card__img:has(.card__img-hover) .card__img-hover{
    position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  }
  .card__img:has(.card__img-hover) .card__img-default{ animation: card-crossfade-default 9s ease-in-out infinite; }
  .card__img:has(.card__img-hover) .card__img-hover{ opacity:0; object-position: top; animation: card-crossfade-hover 9s ease-in-out infinite; }
  /* Stagger every other card half a cycle so the whole grid doesn't
     flip in lockstep. */
  .card:nth-child(even) .card__img-default,
  .card:nth-child(even) .card__img-hover{ animation-delay: -4.5s; }

  .card__img:not(:has(.card__img-hover)){ height: auto; }
  .card__img:not(:has(.card__img-hover)) .card__img-default{ position: static; width: 100%; height: auto; }
}

@keyframes card-crossfade-default{
  0%, 40%{ opacity:1; }
  50%, 90%{ opacity:0; }
  100%{ opacity:1; }
}
@keyframes card-crossfade-hover{
  0%, 40%{ opacity:0; }
  50%, 90%{ opacity:1; }
  100%{ opacity:0; }
}
@media (prefers-reduced-motion: reduce){
  .card__img-default, .card__img-hover{ animation: none !important; }
}
