/* travvel · assets/css/base.css
   Fundação compartilhada do front (Fase 2 do refator). Fonte de verdade: DOCS/produto/DS_Travvel.md (DS v8.9).
   Carregado ANTES do CSS de cada página (<link>). Sem build — só tokens + regras comuns.
   PRODUTO: Fernanda Lisnik Dias · ENGENHARIA: Carlos Henrique Roland */

/* ============================================================
   1. TOKENS (DS §2–§7) — nomes e valores oficiais do Design System
   ============================================================ */
:root {
  /* Sky / Brand */
  --sky-500: #3B78EE;        /* brand principal */
  --sky-600: #2560D6;        /* hover */
  --sky-700: #1a4db8;        /* texto em fundo sky claro / press CTA */
  --sky-100: #EBF1FD;        /* fundo de ícone ativo, fundo de campo auto */
  --sky-200: #D6E4FA;        /* chip ativo */
  --sky-focus: #6398F7;      /* focus ring */

  /* Ink / Navy */
  --ink-900: #0C1B40;        /* texto principal */
  --ink-800: #0E2150;        /* frames, wordmark escuro, superfícies dark */

  /* Slate */
  --slate-900: #0E1E40;      /* texto primário */
  --slate-700: #3a4a6b;      /* texto secundário forte */
  --slate-500: #5C6B8A;      /* texto secundário */
  --slate-400: #9aaac4;      /* texto inativo, placeholders */

  /* Sand */
  --sand-100: #F5F1E8;       /* fundo da página */
  --sand-200: #EAE4D6;       /* botão Neutro (D24: alternativa que não é cancelar) */

  /* Semânticas */
  --palm-500: #18A56E;       /* sucesso, módulo ativo */
  --palm-100: #E1F5EE;
  --ember-500: #F8842A;      /* destaque, atenção, highlight */
  --ember-100: #FEF0E6;
  --coral-500: #E5484D;      /* erro, perigo — SOMENTE destrutivo */
  --coral-100: #FFF5F5;

  /* Superfícies */
  --surface-page: #F5F1E8;
  --surface-card: #FFFFFF;
  --surface-inverse: #0E2150;
  --border-neutral: #e0e4ee;
  --border-light: rgba(14,33,80,0.08);

  /* Tipografia */
  --font-display: 'Sora', sans-serif;
  --font-ui: 'Plus Jakarta Sans', sans-serif;
  --font-mono: 'Space Mono', monospace;

  --text-wordmark: 700 22px/1 var(--font-display);
  --text-h1: 700 24px/1.15 var(--font-display);
  --text-h2: 700 20px/1.2 var(--font-display);
  --text-h3: 700 17px/1.3 var(--font-display);
  --text-body-lg: 400 14px/1.5 var(--font-ui);
  --text-body: 400 13px/1.5 var(--font-ui);
  --text-sm: 400 12px/1.45 var(--font-ui);
  --text-xs: 400 11px/1.45 var(--font-ui);
  --text-label: 600 12px/1 var(--font-ui);
  --text-mono: 400 13px/1 var(--font-mono);

  /* Device / espaçamento (DS §4) */
  --sp-device-w: 390px;
  --sp-device-h: 844px;
  --sp-page-h: 20px;
  --sp-page-top: 12px;
  --sp-section-gap: 8px;
  --sp-title-gap: 16px;
  --sp-card-gap: 12px;
  --sp-safe-bottom: 40px;

  /* Border-radius (DS §6) */
  --radius-screen: 40px;
  --radius-card-lg: 28px;
  --radius-card: 24px;
  --radius-card-sm: 16px;
  --radius-input: 14px;
  --radius-icon: 10px;
  --radius-tag: 8px;
  --radius-pill: 999px;
  --radius-porthole: 44%;

  /* Sombras (DS §7) */
  --shadow-inset: inset 0 1px 3px rgba(14,33,80,0.07), 0 1px 0 rgba(255,255,255,0.9);
  --shadow-glass: 0 1px 6px rgba(14,33,80,0.07);
  --shadow-glass-inner: inset 0 1px 0 rgba(255,255,255,0.6);
  --shadow-fab: 0 2px 12px rgba(14,33,80,0.13), inset 0 1px 0 rgba(255,255,255,0.95);
  --shadow-cta: 0 2px 10px rgba(59,120,238,0.28), inset 0 1px 0 rgba(255,255,255,0.15);
  --shadow-popover: 0 4px 24px rgba(14,33,80,0.14), 0 1px 4px rgba(14,33,80,0.06);

  /* Gradientes de capa / papel (DS §8) */
  --gradient-viajante: linear-gradient(135deg, #F8842A 0%, #3B78EE 100%);
  --gradient-coviajante: linear-gradient(135deg, #18A56E 0%, #3B78EE 100%);
  --capa-1: linear-gradient(135deg, #F8842A 0%, #3B78EE 100%);
  --capa-2: linear-gradient(135deg, #3B78EE 0%, #0C1B40 100%);
  --capa-3: linear-gradient(135deg, #18A56E 0%, #3B78EE 100%);
  --capa-5: linear-gradient(135deg, #5C6B8A 0%, #3B78EE 100%);
}

/* ============================================================
   2. RESET COMUM (idêntico em ~todas as páginas — dedup)
   ============================================================ */
* { box-sizing: border-box; margin: 0; padding: 0; }

input {
  outline: none !important;
  border: none !important;
  box-shadow: none !important;
  -webkit-appearance: none;
  appearance: none;
}

/* ============================================================
   3. MOBILE EDGE-TO-EDGE (opt-in via <body class="edge-mobile">)
   ============================================================
   Telas de PRODUTO (/app/ + /auth/) tiram o molde do iPhone no
   viewport mobile — vira app full-screen. Desktop mantém o frame
   arredondado (útil como preview de UI). Não afeta /prototype/,
   que segue mostrando o molde sempre (showcase pra Fernanda).

   Regras são deliberadamente específicas (body.edge-mobile > seletor)
   pra vencer os CSS por-tela (assets/css/<tela>.css) sem !important.
   ============================================================ */
@media (max-width: 768px) {
  /* Body cobre viewport inteiro (edge-to-edge, bege puro).
     .tv é 100% do body — nenhuma camada visível de diferença.
     Safe-area vai NO .tv-hd (header) — faz o header ficar embaixo do
     notch sem criar "faixa" visível entre body/tv. */
  body.edge-mobile {
    position: fixed;
    inset: 0;
    background: var(--surface-page, #F5F1E8);
    overflow: hidden;
    margin: 0;
  }
  body.edge-mobile .tv {
    width: 100%;
    height: 100%;
    min-height: 0;
    max-width: none;
    max-height: none;
    border-radius: 0 !important;
    border: none !important;
    box-shadow: none !important;
    margin: 0;
    padding: 0;
  }
  body.edge-mobile .tv-island { display: none; }
  body.edge-mobile .sbar      { display: none; }

  /* Header cresce pra acomodar safe-area do notch por cima.
     .hd-normal (position:absolute inset:0) continua cobrindo o element
     inteiro, mas com align-items:center os botões ficam centralizados
     no total (funciona bem visualmente).

     background:transparent — mostra o body direto por trás. Isso mata
     a "faixa" cinza sutil que aparecia com bg:var(--surface-page): o
     browser renderiza layer separada com stacking context (z-index:40),
     causando micro-diferença de cor (~2 pontos RGB abaixo) mesmo com
     variável idêntica. Com transparent, é uma camada só = body. */
  body.edge-mobile .tv-hd,
  body.edge-mobile .tv-hd-mod {
    padding-top: env(safe-area-inset-top, 0px);
    height: auto;
    min-height: 54px;
    background: transparent !important;
  }
  body.edge-mobile .sbar { background: transparent !important; }

  /* iOS Safari faz auto-zoom em qualquer input com font-size < 16px quando
     ele recebe focus. Força 16px em TODOS os campos de entrada em telas
     mobile (produto) — mata o zoom sem precisar bloquear pinch/scale, que
     já é feito pela viewport meta (maximum-scale=1, user-scalable=no).
     !important porque cada CSS por-tela costuma redeclarar font-size:14px/13px. */
  body.edge-mobile input,
  body.edge-mobile textarea,
  body.edge-mobile select {
    font-size: 16px !important;
  }
}

/* ============================================================
   4. BOTÃO VOLTAR COM ÍCONE DA ORIGEM (D31)
   ============================================================
   Variante de .back-btn usada em telas de múltipla origem
   (Memórias, Registrar, Câmbio, Viagem). Sem rótulo textual —
   largura fixa. O ícone da origem é injetado por nav.js a partir
   de TV.getOrigem() (fallback Home). Herda o visual glass do
   .back-btn (fundo/borda/sombra) definido em cada CSS por tela;
   aqui só ajustamos padding/tamanho e o slot do ícone. */
.back-btn.back-btn-orig {
  padding: 6px 10px;
  gap: 4px;
}
.back-btn.back-btn-orig .back-orig-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  color: var(--ink-800);
  flex-shrink: 0;
}
.back-btn.back-btn-orig .back-orig-ico svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ============================================================
   5. SCROLLBAR — REGRA GLOBAL (D24)
   ============================================================
   D24 (Fernanda 2026-08-09): "barra de rolagem NUNCA visível — corta o
   canto arredondado; vira regra global no base.css (hoje 17 de 18
   arquivos escondem, mas classe a classe, então todo container novo
   nasce mostrando)". A regra abaixo cobre qualquer scrollable dentro
   do frame do app (.tv) — inclui sheets, modais, listas, chips, etc.

   Escopo restrito a `.tv` de propósito: preserva scrollbar padrão do
   navegador em conteúdo fora do frame (útil para debug, mockup, telas
   de admin/dev que não usem .tv). As declarações locais em cada CSS
   por-tela permanecem — funcionam como redundância inofensiva; a
   remoção massiva seria "limpeza cosmética" fora do escopo D24. */
.tv,
.tv * { scrollbar-width: none; }
.tv::-webkit-scrollbar,
.tv *::-webkit-scrollbar { display: none; }

/* ============================================================
   6. BOTÃO NEUTRO (.btn-neu) — D24
   ============================================================
   D24 (Fernanda 2026-08-09): 4º papel de botão de sobreposição.
   "bege escuro #EAE4D6 preenchido, texto ink, para a alternativa
   que NÃO é cancelar (ex.: 'Não, só olhei'). Hoje usa o mesmo
   contorno do Cancelar e os dois se confundem".

   Diferente do .btn-cancel (outline puro), o Neutro tem PESO
   visual — comunica "opção legítima, apenas não é a principal".
   Ordem canônica em sobreposição: Cancelar → Neutro → Principal.

   Uso: aplicar apenas quando a spec exigir esse papel (não
   substitui .btn-cancel; não é padrão para toda alternativa). */
.btn-neu {
  flex: 1;
  height: 46px;
  border-radius: 999px;
  background: var(--sand-200);
  border: none;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-800);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  cursor: pointer;
  user-select: none;
  transition: transform 120ms, background 120ms;
}
.btn-neu:active {
  transform: scale(0.96);
  background: #DDD5C0;
}

/* ── SKELETON SHIMMER (Mock 0 completude 2026-08-19) ──
   Loading state global — inicialmente vive só em home.css (extraído aqui
   pra todas as telas usarem sem duplicar). Substitui placeholders inline
   ('US$', 'R$', 'US$ ...', '—') que davam falsa impressão de dado real
   antes do fetch resolver.

   Uso: colar <span class="tv-skel"></span> onde antes tinha o mock.
   Depois de TripsAPI.get resolver no init, substituir por textContent
   real (mesmo padrão de home-trips.js). Fallback pra "—" em .catch.

   Variantes:
     .tv-skel        — default (fundo claro; cards, labels, chips)
     .tv-skel-title  — hero title (fundo escuro/gradient, alpha grande)
     .tv-skel-sub    — hero sub (fundo escuro/gradient, alpha pequeno) */
.tv-skel {
  display: inline-block;
  width: 64px; height: 8px;
  border-radius: 4px;
  vertical-align: middle;
  background: linear-gradient(90deg, #E5E9F0 0%, #F1F4F9 50%, #E5E9F0 100%);
  background-size: 200% 100%;
  animation: tv-shimmer 1.4s ease-in-out infinite;
}
.tv-skel-title {
  display: inline-block;
  width: 200px; height: 24px;
  border-radius: 6px;
  vertical-align: middle;
  background: linear-gradient(90deg, rgba(255,255,255,0.18) 0%, rgba(255,255,255,0.34) 50%, rgba(255,255,255,0.18) 100%);
  background-size: 200% 100%;
  animation: tv-shimmer 1.4s ease-in-out infinite;
}
.tv-skel-sub {
  display: inline-block;
  width: 150px; height: 10px;
  border-radius: 4px;
  vertical-align: middle;
  margin-top: 8px;
  background: linear-gradient(90deg, rgba(255,255,255,0.14) 0%, rgba(255,255,255,0.28) 50%, rgba(255,255,255,0.14) 100%);
  background-size: 200% 100%;
  animation: tv-shimmer 1.4s ease-in-out infinite;
}
@keyframes tv-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ── CITY AUTOCOMPLETE (Fernanda 2026-08-21 Fase 3 auto-detecção país→moeda) ──
   Componente compartilhado (JS: assets/js/city-autocomplete.js) que sugere
   cidades reais da base própria (GeoNames cities500 → travvel.cities) enquanto
   usuário digita. Aplicado nos inputs de cidade dos forms de trip. */
.city-autoc-dropdown {
  position: absolute;
  top: 100%; left: 0; right: 0;
  z-index: 1000;
  margin-top: 4px;
  max-height: 240px;
  overflow-y: auto;
  background: #fff;
  border: 1.5px solid var(--border-neutral, #d8dee8);
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(14, 33, 80, 0.12);
  font-family: 'Plus Jakarta Sans', sans-serif;
}
.city-autoc-item {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px;
  cursor: pointer;
  border-bottom: 1px solid rgba(14, 33, 80, 0.06);
  transition: background 0.12s ease;
}
.city-autoc-item:last-child { border-bottom: none; }
.city-autoc-item:hover { background: rgba(59, 120, 238, 0.06); }
.city-autoc-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-900, #0e2150);
}
.city-autoc-country {
  font-size: 11px;
  color: var(--slate-500, #5a6b8c);
  margin-left: 12px;
  white-space: nowrap;
}
.city-autoc-empty {
  padding: 12px 14px;
  font-size: 12px;
  color: var(--slate-400, #9aaac4);
  font-style: italic;
  text-align: center;
}

/* ── CAL PICKER (Fernanda 2026-08-19 ponto 4) ──
   Componente compartilhado (JS: assets/js/cal-picker.js) que substitui os
   chip pickers de dias (initDias) que existiam duplicados em passeios/
   restaurantes/compras/agenda. Grid mês completo, dias fora da viagem
   esmaecidos, navegação restrita aos meses da viagem. */
.cal-pick {
  padding: 4px 4px 8px;
}
.cal-pick-hd {
  display: flex; align-items: center; justify-content: space-between;
  padding: 4px 8px 10px;
}
.cal-pick-nav {
  background: none; border: none;
  font-size: 22px; line-height: 1; color: var(--ink-800);
  cursor: pointer; user-select: none;
  width: 32px; height: 32px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  transition: background 120ms, transform 120ms;
}
.cal-pick-nav:disabled {
  opacity: 0.24; cursor: not-allowed;
}
.cal-pick-nav:not(:disabled):active {
  background: var(--sand-200); transform: scale(0.94);
}
.cal-pick-month {
  font-size: 14px; font-weight: 700; color: var(--ink-800);
  text-transform: capitalize;
}
.cal-pick-wk {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px;
  padding: 0 4px 6px;
}
.cal-pick-wk div {
  text-align: center;
  font-size: 10px; font-weight: 700; letter-spacing: 0.04em;
  color: var(--slate-400);
}
.cal-pick-grid {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px;
  padding: 0 4px;
}
.cal-pick-day {
  aspect-ratio: 1;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 500;
  color: var(--ink-800);
  border-radius: 10px;
  user-select: none;
  transition: background 120ms, transform 120ms, color 120ms;
}
.cal-pick-day.out-month {
  opacity: 0.28; color: var(--slate-400); font-weight: 400;
}
.cal-pick-day.disabled {
  opacity: 0.28; cursor: not-allowed; font-weight: 400;
}
/* Fernanda 2026-08-24 (bug 3): dias dentro da trip mas já passados — mais
   opaco que .disabled comum + strike sutil pra indicar "passou". Aplicado
   junto com .disabled pelo cal-picker.js. */
.cal-pick-day.past {
  text-decoration: line-through;
  text-decoration-color: rgba(14, 33, 80, 0.35);
}
/* Selecionado no passado: mantém azul (histórico) mas com opacity reduzida
   e strike, sinaliza "foi planejado, já vivido". */
.cal-pick-day.past.selected {
  opacity: 0.55; cursor: not-allowed;
}
.cal-pick-day.in-trip {
  cursor: pointer;
}
.cal-pick-day.in-trip:not(.selected):active {
  background: var(--sand-200); transform: scale(0.92);
}
/* Fernanda 2026-08-21: dia corrente destacado em vermelho — só quando NÃO está
   selecionado (mantém azul se estiver marcado como dia planejado). */
.cal-pick-day.today:not(.selected) {
  box-shadow: inset 0 0 0 1.5px var(--coral-500, #E5484D);
  color: var(--coral-500, #E5484D);
  font-weight: 700;
}
.cal-pick-day.selected {
  background: var(--sky-500); color: #fff; font-weight: 700;
}
