/*
 * base.css — shared PezilloWeb styles built on top of css/theme.css.
 * Source of truth throughout: PezilloWeb/SPEC.md (Sections 1-7).
 */

@import url('theme.css');

/* ---------------- Reset ---------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

/*
 * Bug found on real-device testing (2026-09-28, pezillo.com): tapping any
 * button/link showed an ugly solid gray rectangle over its tap area. That's
 * two separate mobile-browser defaults stacking on top of each other: (1)
 * Chrome/Brave's `-webkit-tap-highlight-color`, a translucent gray flash
 * drawn over the whole tappable box on touch, and (2) the default `:focus`
 * outline, which mobile browsers also apply after a tap (not just keyboard
 * focus) and which renders as a rectangle even on round/pill-shaped buttons.
 * Neither exists in the native Android app (no such touch-feedback treatment
 * in the design), so both are suppressed globally; buttons still get a
 * lightweight custom `:focus-visible` ring for keyboard/accessibility use.
 */
* {
  -webkit-tap-highlight-color: transparent;
}

button,
a {
  outline: none;
}

button:focus-visible,
a:focus-visible {
  outline: 2px solid var(--color-aqua);
  outline-offset: 2px;
}

img {
  display: block;
  max-width: 100%;
}

/*
 * Bug found on real-device testing (2026-09-28, pezillo.com): several
 * components (.paused-actions, .training-flash-overlay, etc.) set their own
 * `display` value in an author stylesheet. The browser's built-in
 * `[hidden] { display: none }` rule lives in the lowest-priority UA
 * stylesheet, so ANY same-specificity author rule wins over it even though
 * specificity is nominally "equal" — the `hidden` attribute was being
 * silently ignored everywhere a component also had its own `display: flex`
 * rule, making paused/training-flash/etc. UI show up incorrectly on load.
 * This single global override (high specificity via !important) makes
 * `hidden` win unconditionally again, everywhere, without having to patch
 * every individual component rule one by one.
 */
[hidden] {
  display: none !important;
}

button {
  font: inherit;
  color: inherit;
}

/* ---------------- Body / page background ---------------- */
/*
 * SPEC.md 4 (bg_gradient*.xml): the texture bitmap is explicitly a single
 * STRETCHED, non-tiling bitmap (android:gravity="fill") — an earlier attempt to
 * tile a small texture caused a visible grid-seam pattern on real devices, so it
 * was deliberately changed to stretch-to-fill instead. Mirrored here with
 * background-size: cover + no-repeat; never `repeat`.
 */
body {
  font-family: 'LT Colored Pencil', sans-serif;
  color: var(--color-text-primary);
  background-color: var(--color-bg-top);
  background-image: var(--bg-texture-image);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  background-attachment: fixed;
  /*
   * Bug found 2026-09-29 (user report on real device: "sigue habiendo
   * scroll" on main/settings, even after .app-view--fixed/.app-view--list
   * already got their own vh->dvh override). Root cause: `100vh` on mobile
   * browsers with a collapsible address bar equals the LARGEST possible
   * viewport (bar collapsed), which is taller than what's actually visible
   * when the bar is showing on page load — so body ends up a few dozen px
   * taller than the visible screen and becomes scrollable by that gap, even
   * though the .app-view--fixed/.app-view--list section INSIDE it is
   * correctly clamped to 100dvh and overflow: hidden. `100dvh` tracks the
   * actual current visible viewport instead, matching the .app-view rules
   * below. Same "100vh first, then 100dvh override" pattern for browsers
   * that don't support dvh yet.
   */
  min-height: 100vh;
  min-height: 100dvh;
}

/* ---------------- Header (SPEC.md 7, "near-universal header row pattern") ---------------- */
.app-header {
  display: flex;
  align-items: center;
}

.app-header__logo {
  /* Default 22px per the shared header pattern (SPEC.md 7 intro). MainActivity's
     own header uses 26px instead (SPEC.md 7.1) — use .app-header--main to bump it. */
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  /*
   * Bug found 2026-09-29 (user report + live pixel verification: "el icono,
   * en el tema claro, no se ha invertido"): this element used to be a plain
   * <img src="ic_app_logo.png">, on the (wrong) assumption documented right
   * here until today that the PNG's own baked-in color "already reads
   * correctly as a dark pencil mark on light paper". Pixel-sampled the
   * actual file 2026-09-29: it is solid WHITE with a varying alpha channel
   * (avg RGB (255,255,255), same file already proven mask-ready by the
   * settings theme-swatch fix, css/pages.css .theme-swatch__icon) — i.e. the
   * exact opposite of that old assumption. A plain <img> of a white glyph is
   * naturally invisible against the light theme's near-white background,
   * which is exactly the bug reported. The Android original is tinted
   * ?attr/colorAqua at runtime (SPEC.md 7 intro: "22dp ImageView tinted
   * ?attr/colorAqua") — colorAqua itself already flips light/dark
   * (css/theme.css --color-aqua: #17160F light / #F2EEE2 dark), so the fix
   * is the same mask-image + background-color technique already proven for
   * the theme-swatch icons, tied to the ACTIVE theme's --color-aqua instead
   * of a fixed one. The markup changed from <img> to a plain masked <span>
   * (see index.html) since CSS mask recolors a background-color layer, not
   * an <img>'s own decoded pixels.
   */
  display: block;
  background-color: var(--color-aqua);
  mask-image: url('../assets/images/ic_app_logo.png');
  -webkit-mask-image: url('../assets/images/ic_app_logo.png');
  mask-size: contain;
  -webkit-mask-size: contain;
  mask-repeat: no-repeat;
  -webkit-mask-repeat: no-repeat;
  mask-position: center;
  -webkit-mask-position: center;
}

.app-header--main .app-header__logo {
  width: 26px;
  height: 26px;
}

.app-header__title {
  flex: 1;
  margin-left: 10px;
  letter-spacing: 0.08em;
  font-size: 18px;
  font-weight: bold;
  color: var(--color-text-primary);
  text-transform: uppercase;
}

/* MainActivity's header title is 17sp / 0.06em tracking instead of 18sp/0.08em
   (SPEC.md 7.1) — main-only override. */
.app-header--main .app-header__title {
  font-size: 17px;
  letter-spacing: 0.06em;
}

/*
 * The ic_divider_lines sketch-divider that used to sit under headers was removed
 * from almost every screen per explicit user request 2026-08-23 (SPEC.md 4, 7).
 * Only activity_session_log.xml keeps it. Intentionally no .app-header divider
 * rule here — pages that need it (session log) can add a one-off element.
 */

/* ---------------- Icon buttons (header nav: training/history/settings) ---------------- */
/*
 * bg_circle_ghost.xml: oval, solid ?attr/colorCardBg — same color as the page
 * background, i.e. an "invisible" circular hit-area (SPEC.md 4). 44x44dp per
 * SPEC.md 7.1 (portrait); landscape shrinks this to 32x32 but we treat that as a
 * responsive concern for the page CSS, not this shared class.
 */
.icon-btn {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  /*
   * Bug found on real-device testing (2026-09-28): a flat --color-card-bg
   * fill only matches the PAGE'S base color, not what the page actually
   * shows — the page also paints the paper/chalkboard texture image over
   * that color (see body{} in this same file). A plain flat circle on top
   * of a textured backdrop reads as a visible solid dark blob instead of
   * the intended "invisible ghost button" (bg_circle_ghost.xml originally
   * relied on being on a plain color background, which the web version
   * isn't). Fix: paint the SAME texture image with the SAME
   * background-attachment: fixed as body{} — because `fixed` positions the
   * image relative to the viewport (not the element), the button's patch of
   * texture lines up pixel-for-pixel with the page behind it, so the button
   * genuinely disappears into the background again, on both themes.
   */
  background-color: var(--color-card-bg);
  background-image: var(--bg-texture-image);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  background-attachment: fixed;
  border: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
  cursor: pointer;
  flex-shrink: 0;
}

.icon-btn + .icon-btn {
  margin-left: 10px;
}

/*
 * Bug found 2026-09-29 (user reports: "el icono, en el tema claro... hay
 * zonas que no se ven (los tres iconos, por ejemplo)" AND separately "los
 * tres iconos... los quiero más grandes"). Same root cause as
 * .app-header__logo above (ic_history/ic_settings/ic_training_plan.png are
 * ALSO solid white+alpha, pixel-verified 2026-09-29) — recolored via the
 * same mask-image + background-color technique, tinted var(--color-aqua)
 * so it flips with the active theme.
 *
 * Sizing: the old rule hardcoded these to a fixed 22px, well below the
 * ~36px actually available inside the 44px .icon-btn box once its 4px
 * padding is subtracted — SPEC.md 7 intro's own Android spec is a 44dp
 * FrameLayout, `padding=4dp`, `scaleType="fitCenter"` (i.e. the glyph fills
 * whatever space padding leaves, not a fixed smaller size). `width/height:
 * 100%` here does the equivalent of fitCenter within that padded box,
 * which is what "más grandes, misma proporción que en Android" asked for.
 */
.icon-btn__glyph {
  display: block;
  width: 100%;
  height: 100%;
  background-color: var(--color-aqua);
  mask-size: contain;
  -webkit-mask-size: contain;
  mask-repeat: no-repeat;
  -webkit-mask-repeat: no-repeat;
  mask-position: center;
  -webkit-mask-position: center;
}

.icon-btn__glyph--training {
  mask-image: url('../assets/images/ic_training_plan.png');
  -webkit-mask-image: url('../assets/images/ic_training_plan.png');
}

.icon-btn__glyph--history {
  mask-image: url('../assets/images/ic_history.png');
  -webkit-mask-image: url('../assets/images/ic_history.png');
}

.icon-btn__glyph--settings {
  mask-image: url('../assets/images/ic_settings.png');
  -webkit-mask-image: url('../assets/images/ic_settings.png');
}

/* ---------------- Cards ---------------- */
/*
 * SPEC.md 4: bg_card.xml / bg_card_accent_top.xml both had their <stroke> removed
 * in a deliberate visual experiment ("PRUEBA VISUAL", user request 2026-08-23),
 * leaving corner-radius-only shapes with NO solid fill and NO stroke — content
 * floats directly on the page's paper/slate texture with no visible card
 * silhouette. We replicate that literally: no background, no border, just the
 * radius + padding, so a future hover/focus treatment has a clear shape to key
 * off if ever reintroduced (SPEC.md flags this as a legitimate open question for
 * the web rebuild, since web needs affordances native touch didn't).
 */
.card {
  border-radius: 16px;
  padding: 16px;
  background: transparent;
  border: none;
}

/* bg_card_accent_top.xml is drawable-identical to bg_card.xml today (no visual
   "accent" left after the stroke removal) — kept as an alias class per SPEC.md 4
   so markup can still express "this is the primary/accent card" semantically. */
.card--accent-top {
  border-radius: 16px;
  padding: 16px;
  background: transparent;
  border: none;
}

/*
 * bg_card_dark.xml deliberately KEEPS its fill (SPEC.md 4) — used for the
 * debug/log panel because its content (monospace log text) needs a distinct
 * panel, unlike normal content cards.
 */
.card--dark {
  background: var(--color-card-bg-dark);
  border-radius: 12px;
  padding: 14px;
}

/* ---------------- Pill buttons ---------------- */
/*
 * SPEC.md 4 is explicit that EVERY *.xml pill drawable (bg_button_pill,
 * _aqua, _danger, _warning) currently has no solid fill and no stroke — all
 * differences between them today are purely which drawable MainActivity swaps
 * in at runtime, but visually, with fill+stroke both stripped, they render
 * identically as bare shapes. Since a completely colorless button set would
 * make Pause/Finish/Resume indistinguishable on the web (native taps rely on
 * position + label text, which is enough on a physical button but weaker
 * feedback on a web pill with no chrome at all), we use TEXT COLOR as the one
 * remaining differentiator: aqua/danger/warning classes set only `color`,
 * still with fully transparent background/border, staying faithful to "no
 * fill, no stroke" while keeping some state feedback. This is a judgment call
 * where SPEC.md is ambiguous ("sin relleno en absoluto" vs "colorea algo") —
 * documented here explicitly per the project's instruction to flag such calls.
 */
.btn-pill {
  border-radius: 45px;
  background: transparent;
  border: none;
  font-weight: bold;
  letter-spacing: 0.08em;
  color: var(--color-text-primary);
  cursor: pointer;
  padding: 14px 24px;
  text-align: center;
  text-transform: none;
}

.btn-pill--aqua {
  color: var(--color-aqua);
}

.btn-pill--danger {
  color: var(--color-danger-red);
}

.btn-pill--warning {
  color: var(--color-warning-yellow);
}

/* START button: 28sp bold (SPEC.md 7.1 btnStartStop). */
.btn-pill--lg {
  font-size: 28px;
}

/* RESUME/FINALIZAR/PAUSAR and most other pills: 17sp/16sp bold (SPEC.md 7.1, 7.10). */
.btn-pill--md {
  font-size: 17px;
}

.btn-pill--sm {
  font-size: 15px;
}

/* ---------------- Inputs ---------------- */
/* bg_input_pill.xml: corner radius 16dp, no fill/stroke (SPEC.md 4) — same
   "floats on page" treatment as cards/buttons. */
/*
 * Bug found 2026-09-29 (user report: "el campo de texto del tamaño de la
 * piscina y el viraje, tienen como una sombra; tendría que no tenerla; ser
 * transparentes, como los demás botones"). Root cause: this rule set
 * `background: transparent; border: none;` but never reset the browser's
 * own native form-control rendering (`appearance`) or `box-shadow` —
 * mobile Chrome/Brave's default `<input type="number">` chrome can still
 * paint its own subtle rounded-box shadow/bezel underneath author styles in
 * that case, the same class of bug as the START button's stray box-shadow
 * fixed earlier today (css/main.css .start-stop-btn). Explicit
 * `appearance: none` + `box-shadow: none` fully suppresses it, matching
 * every other borderless/fill-less control in this design.
 *
 * Second bug found 2026-09-29 (user report: this "shadow" was STILL there
 * after the appearance/box-shadow fix above). Root cause was different from
 * what that first fix addressed: this rule also set `border-bottom: 1px
 * solid ...` together with `border-radius: 16px` on the SAME box — a
 * border-radius rounds every corner the border passes through, so a
 * bottom-only border on a radius'd box doesn't render as a flat line, it
 * curves up at both ends into a "smile"/boat shape, which read as a stray
 * shadow rather than an intentional underline. Checked the Android original
 * (`bg_input_pill.xml`, referenced in this same file's earlier comment):
 * it has NO fill and NO stroke at all — same "floats on the page" treatment
 * as every other pill control (buttons, cards) — the border-bottom here was
 * a web-only addition never in the source design. Removed entirely so
 * these fields are genuinely borderless/transparent, matching Android and
 * every other control. The focus indicator moves to the shared
 * `:focus-visible` outline pattern below instead of a border-color swap,
 * since outline doesn't inherit border-radius's per-corner curving the same
 * way and won't reproduce this same artifact.
 */
.input-pill {
  border-radius: 16px;
  background: transparent;
  border: none;
  box-shadow: none;
  appearance: none;
  -webkit-appearance: none;
  padding: 10px 14px;
  font-family: inherit;
  font-size: 16px;
  color: var(--color-text-primary);
  width: 100%;
}

.input-pill:focus {
  outline: none;
}

.input-pill:focus-visible {
  outline: 2px solid var(--color-aqua);
  outline-offset: 2px;
}

/* ---------------- Status dot ---------------- */
/*
 * bg_dot.xml (SPEC.md 4): a layered oval — (1) a large 25%-white halo oval, (2)
 * a small 5x5dp solid oval — the whole drawable is tinted one runtime color
 * (aqua/coral/text_muted), which recolors both layers together via the tint's
 * own alpha preservation, producing a soft glow without any real blur. We
 * replicate with a small circle (5-6px) plus a box-shadow "halo" ring in the
 * same currentColor family at ~25% opacity, both driven off one modifier class
 * so a single class swap updates both parts together, matching the single-tint
 * behavior.
 */
.status-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--color-text-muted);
  box-shadow: 0 0 0 6px rgba(var(--color-text-muted-rgb), 0.25);
}

.status-dot--aqua {
  background: var(--color-aqua);
  box-shadow: 0 0 0 6px rgba(var(--color-aqua-rgb), 0.25);
}

.status-dot--coral {
  background: var(--color-coral);
  box-shadow: 0 0 0 6px rgba(var(--color-coral-rgb), 0.25);
}

.status-dot--muted {
  background: var(--color-text-muted);
  box-shadow: 0 0 0 6px rgba(var(--color-text-muted-rgb), 0.25);
}

/* ---------------- Progress bar ---------------- */
/* bg_progress_track.xml / bg_progress_fill.xml (SPEC.md 4): reduced from an
   earlier 8dp to 3dp tall per user request; track = card-bg-dark, fill = aqua,
   both 4dp corner radius. */
.progress-track {
  width: 100%;
  height: 3px;
  border-radius: 4px;
  background: var(--color-card-bg-dark);
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  border-radius: 4px;
  background: var(--color-aqua);
  width: 0%;
  /* width set by JS at runtime, mirrors trainingProgressFill's layout_weight */
}

/* ---------------- Dialogs ---------------- */
/*
 * dialog_confirm.xml / dialog_paste_training_plan.xml (SPEC.md 7.10/7.11):
 * bg_dialog.xml is a FLAT theme color (?attr/colorCardBg), 20dp radius — the
 * SPEC explains a bitmap-texture background was tried and reverted for
 * variable-size dialog windows because a bitmap inside a layer-list doesn't
 * reliably stretch/crop to an unknown final size; a flat opaque color is the
 * robust choice. Root margin 24dp, padding 20dp in the source layout.
 */
.dialog-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 1000;
}

.dialog-box {
  background: var(--color-card-bg);
  border-radius: 20px;
  padding: 20px;
  width: 100%;
  max-width: 340px;
}

.dialog-box__title {
  letter-spacing: 0.02em;
  font-size: 20px;
  font-weight: bold;
  color: var(--color-text-primary);
  margin: 0;
}

.dialog-box__message {
  margin-top: 10px;
  font-size: 16px;
  color: var(--color-text-secondary);
}

.dialog-box__actions {
  display: flex;
  margin-top: 20px;
  gap: 12px;
}

.dialog-box__actions .btn-pill {
  flex: 1;
  padding-top: 12px;
  padding-bottom: 12px;
  font-size: 16px;
}

/* ---------------- Text utilities ---------------- */
.text-secondary {
  color: var(--color-text-secondary);
}

.text-muted {
  color: var(--color-text-muted);
}

/* ---------------- SPA view sections ---------------- */
/*
 * All 7 screens now live as sibling <section class="app-view" id="view-XXX">
 * elements inside one shared shell document (see js/app.js's header comment
 * for why: turning the app into a real SPA is what lets a session's camera
 * survive the user looking at Ajustes/Historial/Entrenamientos, matching
 * Android's SessionForegroundService). js/app.js toggles the `hidden`
 * attribute on these to show exactly one at a time; the global
 * `[hidden] { display: none !important }` rule above (added earlier for an
 * unrelated bug, see its own comment) is what makes that toggle reliable
 * even though several `.app-view` variants below also set their own
 * `display` value.
 *
 * Task brief mapping (verified against the native XML layouts in
 * PezilloV2/app/src/main/res/layout/, see the task brief for the exact
 * per-screen reasoning) — three treatments:
 *
 *  - `.app-view--fixed` (main, settings): Android has NO ScrollView here
 *    (or explicitly should behave as if it didn't, per user request for
 *    settings) — the view occupies exactly the viewport height, no page
 *    scroll, ever.
 *  - `.app-view--list` (history, training-plans, training-plan-edit):
 *    Android's root is a plain (non-scrolling) LinearLayout that CONTAINS a
 *    RecyclerView — so the screen itself doesn't scroll, but the list
 *    inside it does. Header/controls around the list use `.view-fixed`
 *    (flex-shrink: 0); the list itself uses `.scroll-region`
 *    (flex: 1 1 auto + overflow-y: auto).
 *  - `.app-view--scroll` (stats, session-detail): Android uses a real
 *    ScrollView(fillViewport=true) — the whole page can scroll if content
 *    overflows. This is the pre-existing default `.page` behavior
 *    (min-height: 100vh, page/document scrolls normally) and needs no
 *    special treatment beyond it.
 */
.app-view {
  display: flex;
  flex-direction: column;
}

/* `height: 100vh` first, then `100dvh` overriding it in browsers that
   support dvh — accounts for mobile browser chrome (address bar, etc.)
   per the task brief's explicit instruction. */
.app-view--fixed {
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

.app-view--list {
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

/* Header/controls that must NOT shrink or scroll away in a `.app-view--list`
   screen (mirrors the fixed chrome around Android's RecyclerView). */
.view-fixed {
  flex-shrink: 0;
}

/* The scrollable list itself inside a `.app-view--list` screen. `min-height:
   0` is required for a flex child to actually be allowed to shrink below its
   content size — without it `overflow-y: auto` never kicks in inside a flex
   column. */
.scroll-region {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

/* Intermediate flex-column wrapper for a `.app-view--list` screen whose
   scrollable list has its OWN fixed sub-header above it (history's
   Fecha/Hora/... column-title row) — the wrapper grows to fill the
   remaining space, and its `.scroll-region` child (not the wrapper itself)
   is what actually scrolls. */
.view-grow {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.app-view--scroll {
  min-height: 100vh;
}

/* ---------------- Page container ---------------- */
/*
 * The original layouts are single-column, padding=20dp, match_parent width
 * (mobile-only app). For desktop we simply cap the width so the "paper" column
 * reads well instead of stretching edge-to-edge, and center it — no distinct
 * desktop layout is warranted since the design is intrinsically one column
 * (SPEC.md 7 intro: "matching a stated user preference for no horizontal
 * scroll on any screen").
 */
.page {
  max-width: 480px;
  margin: 0 auto;
  padding: 20px;
}

/* ---------------- Monospace overrides ---------------- */
/*
 * SPEC.md 5: android:fontFamily="monospace" appears in exactly three places —
 * the debug label + detection history log (activity_main.xml), and the
 * exported session log (activity_session_log.xml) — all "raw technical log"
 * views deliberately kept monospace for column alignment, overriding the
 * pencil font.
 */
.monospace {
  font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
}
