/* ==========================================================================
   FAMILY SU v18.1 — PREMIUM DESIGN SYSTEM (evolution of the original v17
   identity, not a replacement). Loaded after styles.css; additive only —
   styles.css is never rewritten. Deep-water blue evolution: richer, deeper
   navy/ocean tones instead of the original's flatter sky-blue gradient, a
   controlled muted-teal micro-accent (used sparingly, never as an equal
   co-primary), and a genuine charcoal-navy dark mode. Differentiation comes
   from motion/depth/layering, not from abandoning blue.
   ========================================================================== */

/* ==========================================================================
   TOKENS
   ========================================================================== */
:root {
  --radius-control: 13px;
  --radius-card: 20px;
  --radius-modal: 26px;

  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 24px; --space-6: 32px;

  --motion-fast: 130ms; --motion-normal: 210ms; --motion-slow: 340ms;
  --motion-ui: 210ms; --motion-flow: 480ms; --motion-success: 850ms;
  --ease-standard: cubic-bezier(.2,.7,.3,1);
  --ease-fluid: cubic-bezier(.19,1,.22,1);
  --ripple-opacity: .16;
  --flow-line-opacity: .34;

  /* Dock geometry, named so every page reserves exactly enough space and no
     more: dock content height + its raised offset from the edge + a little
     breathing room, plus the device's own safe-area inset. Icon-only mode
     (<=430px) has a shorter dock than the labeled mode, so this is
     recomputed per breakpoint below rather than kept as one fixed number. */
  --dock-height: 64px; --dock-offset: 14px; --dock-breathing: 18px;
  --bottom-dock-space: calc(var(--dock-height) + var(--dock-offset) + var(--dock-breathing) + env(safe-area-inset-bottom));

  /* v18.2 brand palette: water-blue primary + a restrained plum/purple
     secondary, with a sparing pink micro-highlight (never a text color,
     never a semantic color — used only for the droplet's top highlight and
     the rare celebratory accent). All values below verified >=6:1 against
     their surface before being applied — see PREMIUM-DESIGN-REPORT.md. */
  --accent: #2156ab;
  --accent-deep: #132f72;
  --accent-2: #704d9d;
  --accent-hover: #1a4993;
  --accent-active: #143a78;
  --accent-soft: #f2f0f9;
  --accent-text: #1a4993;
  --accent-pink: #da819e;

  --surface-1: #ffffff;
  --surface-2: #f8f7fb;
  --surface-3: #efedf6;
  --border-subtle: #e6e3f0;
  --border-strong: #cfc9e3;
  --text-primary: #191c3a;
  --text-secondary: #514f6e;
  --text-tertiary: #5f5d7d;

  --income: #157a53;
  --expense: #c23f3f;
  --transfer: #3f6fa8;
  --danger: #c23f3f;
  --warning: #a8721f;

  --shadow-1: 0 1px 2px rgba(11,35,68,.06);
  --shadow-2: 0 10px 26px rgba(11,35,68,.10);
  --shadow-3: 0 24px 50px rgba(11,35,68,.16);
}

:root[data-theme="dark"] {
  --surface-1: #17142a; --surface-2: #120f22; --surface-3: #201c38;
  --border-subtle: #2c2645; --border-strong: #3e365c;
  --text-primary: #f2f0fa; --text-secondary: #c3bcdb; --text-tertiary: #a89fc4;
  --accent: #6394e3; --accent-hover: #7ea6ea; --accent-2: #ae90d5;
  --accent-soft: #2e2442; --accent-text: #82abed; --accent-pink: #e79db6;
  --income: #4bbd8f; --expense: #e28a82; --danger: #e28a82;
  --shadow-1: 0 1px 2px rgba(0,0,0,.4); --shadow-2: 0 12px 28px rgba(0,0,0,.45); --shadow-3: 0 26px 54px rgba(0,0,0,.55);
}
:root[data-theme="dark"] body { background: linear-gradient(180deg,#0d0b18,#100d1e 45%,#120f22) !important; }

/* v18.4 Pink theme (internal data-theme value stays "purple" — see below) —
   a third explicit choice alongside Light/Dark (not tied to OS "system"
   preference; picked deliberately). Redesigned from the original v18.3
   "Purple" theme after human design feedback that it read as an
   unconvincing generic-purple reskin rather than a distinct premium
   identity. Rose/raspberry now carries the PRIMARY accent role (Light
   keeps blue primary); the old demoted-blue secondary is gone entirely —
   --accent-2 is now a muted plum, used ONLY in gradients (hero, mini-bar,
   chart bars, goal-wizard step indicator) for a controlled violet
   undertone, never as a solid fill/text/border color, so there is no
   brand-blue (or brand-violet-as-if-primary) surface anywhere in this
   theme. Semantic colors (income/expense/danger/warning) are deliberately
   left unchanged from :root — surfaces stay light-luminance, so the same
   values that pass contrast in Light theme still pass here.

   IMPORTANT — internal/DB compatibility: the selector below is
   `[data-theme="purple"]` and every user_preferences.theme row in
   production still stores the literal string "purple" when a user picks
   "Pink" in the UI. This is deliberate: renaming the internal enum would
   require a schema/constraint migration and would silently invalidate
   every existing user's stored preference. Only the human-facing label
   changed (Mor/Purple -> Pembe/Pink); the persisted value, the CSS
   selector, and every internal identifier stay "purple". See
   BRAND-GUIDE.md and PROJECT_STATUS.md for the full rationale. */
:root[data-theme="purple"] {
  --surface-1: #fffdfe; --surface-2: #fcf5f8; --surface-3: #f8ecf1;
  --border-subtle: #f3d9e3; --border-strong: #e3adc3;
  --text-primary: #341321; --text-secondary: #6b4256; --text-tertiary: #7d5266;
  --accent: #ad1457; --accent-deep: #6b0d38; --accent-hover: #c2185b; --accent-active: #8e0e46;
  --accent-2: #7d4f9e; --accent-soft: #fce8ef; --accent-text: #8e0e46; --accent-pink: #f48fb1;
  --shadow-1: 0 1px 2px rgba(107,13,56,.08); --shadow-2: 0 10px 26px rgba(107,13,56,.14); --shadow-3: 0 24px 50px rgba(107,13,56,.20);
}
:root[data-theme="purple"] body { background: linear-gradient(180deg,#fcf1f5,#fdf7f9 45%,#fbeef3) !important; }

/* Purple leftover-brand-blue fixes (audit pass): three legacy styles.css
   rules use hardcoded blue values that bypass the token system entirely
   (not var(--blue)/var(--blue2), literal hex/rgba) and were never themed
   for Purple, unlike every other primary-color surface in the app. Scoped
   to the Purple theme only — Light/Dark are unaffected and unaudited here. */
:root[data-theme="purple"] .hero { box-shadow: 0 18px 42px color-mix(in srgb, var(--accent-deep) 45%, transparent) !important; }
:root[data-theme="purple"] .central-add .droplet-svg { filter: drop-shadow(0 10px 16px color-mix(in srgb, var(--accent-deep) 45%, transparent)); }
:root[data-theme="purple"] .central-add:active .droplet-svg { filter: drop-shadow(0 4px 8px color-mix(in srgb, var(--accent-deep) 40%, transparent)); }
:root[data-theme="purple"] .row[data-account]:hover,
:root[data-theme="purple"] .row[data-transaction]:hover,
:root[data-theme="purple"] .row[data-investment]:hover,
:root[data-theme="purple"] .row[data-obligation]:hover { background: color-mix(in srgb, var(--accent) 7%, transparent) !important; }

/* ==========================================================================
   BASE — apply tokens to the app's existing structure
   ========================================================================== */
body { color: var(--text-primary) !important; }
.app { padding-bottom: var(--bottom-dock-space) !important; }
.auth-card,.card,.summary,.sheet,.profile-actions button,.quick-grid button {
  background: var(--surface-1) !important; border-color: var(--border-subtle) !important;
  border-radius: var(--radius-card) !important; box-shadow: var(--shadow-2) !important; color: var(--text-primary) !important;
}
.tagline,.muted,small,.row small,.summary span { color: var(--text-secondary) !important; }
.auth-card label,.sheet label,.filters label { color: var(--text-secondary) !important; }
.row { border-bottom-color: var(--border-subtle) !important; }
.primary { background: linear-gradient(135deg,var(--accent),var(--accent-deep)) !important; border-radius: var(--radius-control) !important; }
.secondary { background: var(--accent-soft) !important; color: var(--accent-text) !important; border-radius: var(--radius-control) !important; }
.text-button { color: var(--text-secondary) !important; }
.auth-card input,.auth-card select,.sheet input,.sheet select,.sheet textarea,.filters input,.filters select {
  background: var(--surface-2) !important; color: var(--text-primary) !important; border-color: var(--border-subtle) !important;
  border-radius: var(--radius-control) !important; transition: border-color var(--motion-fast) var(--ease-standard);
}
.auth-card input:focus,.auth-card select:focus,.sheet input:focus,.sheet select:focus,.sheet textarea:focus {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent) !important;
}
.positive,.income-text { color: var(--income) !important; }
.negative,.expense-text { color: var(--expense) !important; }
.link { color: var(--accent-text) !important; }
.avatar { background: linear-gradient(135deg,var(--accent),var(--accent-deep)) !important; }
.bottom-nav { background: color-mix(in srgb, var(--surface-1) 93%, transparent) !important; border-top-color: var(--border-subtle) !important; }
.bottom-nav button.active { color: var(--accent) !important; }
/* Family SU water-drop FAB — "damlaya damlaya göl olur." The shape carries
   the brand meaning; no literal text about it appears in the UI. */
.central-add {
  background: transparent !important; width: 48px !important; height: 64px !important;
  border-radius: 0 !important; padding: 0 !important; margin: -32px auto 0 !important;
  display: block; box-shadow: none !important;
}
.central-add .droplet-svg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  filter: drop-shadow(0 10px 16px rgba(8,45,84,.38));
  transition: filter var(--motion-ui) var(--ease-standard);
}
.central-add .droplet-highlight { fill: rgba(255,255,255,.32); }
.central-add .plus-mark {
  display: block !important; position: absolute; left: 50%; top: 48px; transform: translate(-50%,-50%) rotate(0deg);
  color: #fff; font-size: 22px; font-weight: 300; line-height: 1; pointer-events: none;
  transition: transform var(--motion-ui) var(--ease-fluid);
}
.central-add:active .droplet-svg { filter: drop-shadow(0 4px 8px rgba(8,45,84,.30)); transform: scale(.96); }
.central-add.is-open .plus-mark { transform: translate(-50%,-50%) rotate(45deg); }
.modal-close { background: var(--surface-2) !important; border-color: var(--border-subtle) !important; color: var(--text-primary) !important; }
.sheet { border-radius: var(--radius-modal) var(--radius-modal) 0 0 !important; }
.handle { background: var(--border-strong) !important; }
.badge,.status-pill { background: var(--accent-soft) !important; color: var(--accent-text) !important; }
.notify-btn { background: var(--accent-soft) !important; color: var(--accent-text) !important; }
.mini-bar { background: var(--surface-3) !important; }
.mini-bar>span { background: linear-gradient(90deg,var(--accent),var(--accent-2)) !important; }
.danger-button { background: color-mix(in srgb, var(--danger) 10%, var(--surface-1)) !important; color: var(--danger) !important; border-color: color-mix(in srgb, var(--danger) 35%, var(--border-subtle)) !important; border-radius: var(--radius-control) !important; }
.split-row button { background: color-mix(in srgb, var(--danger) 12%, var(--surface-1)) !important; color: var(--danger) !important; }
.hero { background: linear-gradient(160deg,var(--accent-deep) 0%,var(--accent) 55%,color-mix(in srgb, var(--accent) 68%, var(--accent-2) 32%) 100%) !important; border-radius: var(--radius-card) !important; position: relative; overflow: hidden; }
.auth-tabs button,.modal-tabs button,.currency-switch button { background: var(--surface-2) !important; border-color: var(--border-subtle) !important; color: var(--text-primary) !important; border-radius: var(--radius-control) !important; }
.auth-tabs button.active,.modal-tabs button.active,.currency-switch button.active { background: var(--accent-soft) !important; color: var(--accent-text) !important; border-color: color-mix(in srgb, var(--accent) 40%, var(--border-subtle)) !important; }
.loader { border-color: var(--border-subtle) !important; border-top-color: var(--accent) !important; }
.demo-note,.info-note { background: var(--accent-soft) !important; color: var(--text-secondary) !important; }
.chart-bars .monthbar i { background: linear-gradient(180deg,var(--accent-2),var(--accent)) !important; }
.notification-item.unread b { color: var(--accent-text) !important; }
.notification-item p { color: var(--text-primary) !important; }

/* ==========================================================================
   MOTION — water/flow vocabulary (unchanged proven CSS-only techniques)
   ========================================================================== */
.primary { position: relative; overflow: hidden; }
.primary::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: radial-gradient(circle at var(--ripple-x,50%) var(--ripple-y,50%), rgba(255,255,255,var(--ripple-opacity)) 0%, transparent 60%);
  opacity: 0; transition: opacity var(--motion-normal) var(--ease-standard);
}
.primary:active::after { opacity: 1; }
/* Droplet ripple — clipped to the exact drop silhouette, not a plain circle */
.central-add { position: relative; overflow: visible; }
.central-add::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  clip-path: path('M24 3C24 3 4 29 4 43C4 54.5 13 62 24 62C35 62 44 54.5 44 43C44 29 24 3 24 3Z');
  background: radial-gradient(circle at 50% 68%, rgba(255,255,255,.32) 0%, transparent 65%);
  opacity: 0; transition: opacity var(--motion-normal) var(--ease-standard);
}
.central-add:active::after { opacity: 1; }

.hero::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 20%, rgba(255,255,255,var(--flow-line-opacity)) 45%, transparent 70%);
  background-size: 200% 100%; background-position: -40% 0;
  animation: su-flow calc(var(--motion-slow) * 2.2) var(--ease-fluid) 1;
}
@keyframes su-flow { to { background-position: 140% 0; } }

/* Waterline: a subtle horizontal line low in the hero card, its vertical
   position encodes "how full" the period feels — used on the dashboard hero
   and reused identically for goal progress capsules (section 13/31). */
.hero-waterline {
  position: absolute; left: 0; right: 0; bottom: var(--waterline-pos, 18%); height: 1px;
  background: rgba(255,255,255,.22); pointer-events: none;
  transition: bottom var(--motion-slow) var(--ease-fluid);
}

@media (hover:hover) and (pointer:fine) {
  .card.premium { position: relative; }
  .card.premium::after {
    content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0;
    background: linear-gradient(200deg, rgba(255,255,255,.5), transparent 55%);
    transition: opacity var(--motion-normal) var(--ease-standard);
  }
  .card.premium:hover::after { opacity: .5; }
}

@keyframes su-confirm-pulse { 0%{transform:scale(1)} 40%{transform:scale(1.015)} 100%{transform:scale(1)} }
.su-value-changed { animation: su-confirm-pulse var(--motion-slow) var(--ease-standard); }

.page { transition: opacity var(--motion-normal) var(--ease-standard), transform var(--motion-normal) var(--ease-standard); }
.page:not(.active) { opacity: 0; }
.page.active { opacity: 1; }
.modal .sheet { animation: su-sheet-reveal var(--motion-normal) var(--ease-fluid); }
@keyframes su-sheet-reveal { from { transform: translateY(16px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }

/* Transaction direction cue — left accent bar, static (not re-animated on
   every re-render, since the app fully re-renders lists via innerHTML) */
.row.tx-income::before,.row.tx-expense::before,.row.tx-transfer::before {
  content: ""; display: inline-block; width: 3px; align-self: stretch; border-radius: 3px; margin-right: 2px;
}
.row.tx-income { position: relative; }
.row.tx-income::before { background: var(--income); }
.row.tx-expense::before { background: var(--expense); }
.row.tx-transfer::before { background: var(--transfer); }

/* ==========================================================================
   GOALS COMPONENTS
   ========================================================================== */
.goal-card { background: var(--surface-1); border: 1px solid var(--border-subtle); border-radius: var(--radius-card); padding: var(--space-4); box-shadow: var(--shadow-2); }
.goal-card + .goal-card { margin-top: var(--space-3); }
.goal-card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-2); margin-bottom: var(--space-2); }
.goal-card-head h2 { margin: 0; font-size: 15px; }
.goal-card-head small { display: block; color: var(--text-secondary); margin-top: 2px; }
.goal-status-pill { font-size: 11px; font-weight: 700; padding: 4px 9px; border-radius: 999px; white-space: nowrap; }
.goal-status-comfortable,.goal-status-on_track { background: color-mix(in srgb, var(--income) 14%, var(--surface-1)); color: var(--income); }
.goal-status-attention { background: color-mix(in srgb, var(--warning) 16%, var(--surface-1)); color: var(--warning); }
.goal-status-high_pace,.goal-status-exceeded { background: color-mix(in srgb, var(--danger) 14%, var(--surface-1)); color: var(--danger); }
.goal-status-savings_achieved { background: color-mix(in srgb, var(--income) 14%, var(--surface-1)); color: var(--income); }
.goal-status-savings_in_progress,.goal-status-unresolvable { background: var(--accent-soft); color: var(--accent-text); }

.goal-waterline { height: 14px; border-radius: 999px; background: var(--surface-3); overflow: hidden; margin: var(--space-3) 0; position: relative; }
.goal-waterline > span { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg,var(--accent-deep),var(--accent)); transition: width var(--motion-slow) var(--ease-fluid); }
.goal-waterline.risk > span { background: linear-gradient(90deg,#8a3030,var(--danger)); }
.goal-waterline.savings > span { background: linear-gradient(90deg,#0c5c3f,var(--income)); }

.goal-stat-grid { display: grid; grid-template-columns: repeat(2,1fr); gap: var(--space-3); margin-top: var(--space-3); }
.goal-stat-grid.wide { grid-template-columns: repeat(4,1fr); }
.goal-stat { }
.goal-stat span { display: block; font-size: 11px; color: var(--text-secondary); margin-bottom: 3px; }
.goal-stat b { font-size: 15px; }
.goal-insight { margin-top: var(--space-3); padding: var(--space-3); border-radius: var(--radius-control); background: var(--accent-soft); color: var(--text-primary); font-size: 13px; line-height: 1.5; }

.goal-templates { display: grid; grid-template-columns: 1fr; gap: var(--space-2); }
.goal-template-card { text-align: left; border: 1px solid var(--border-subtle); background: var(--surface-1); border-radius: var(--radius-card); padding: var(--space-4); }
.goal-template-card b { display: block; margin-bottom: 3px; }
.goal-template-card small { color: var(--text-secondary); }

.goal-wizard-steps { display: flex; gap: 6px; margin-bottom: var(--space-4); }
.goal-wizard-steps span { flex: 1; height: 4px; border-radius: 999px; background: var(--surface-3); }
.goal-wizard-steps span.done { background: var(--accent); }
.goal-wizard-steps span.active { background: var(--accent-2); }

.goal-empty { text-align: center; padding: var(--space-6) var(--space-4); color: var(--text-secondary); }
.goal-empty b { display: block; color: var(--text-primary); font-size: 16px; margin-bottom: 6px; }

/* Goals/Budget premium pass (v18.3) — plan-type accent bar + richer template
   cards + a segmented period-tab look consistent with the auth-tabs/dock
   indicator language, so "Hedefler & Bütçe" reads as a first-class feature
   area rather than a generic list. */
.goal-card { position: relative; overflow: hidden; }
.goal-card::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: linear-gradient(180deg, var(--accent-2), var(--accent));
}
.goal-card.pulse-attention::before { background: linear-gradient(180deg, var(--warning), var(--danger)); }

#plan-period-toggle.quick-grid { grid-template-columns: repeat(4,1fr); background: var(--surface-2); border: 1px solid var(--border-subtle); border-radius: var(--radius-control); padding: 4px; gap: 2px; }
#plan-period-toggle button { border: 0 !important; background: transparent !important; border-radius: calc(var(--radius-control) - 3px) !important; padding: 8px 4px !important; }
#plan-period-toggle button.active { background: var(--surface-1) !important; box-shadow: var(--shadow-1); }
#plan-period-toggle button.active b,#plan-period-toggle button.active span { color: var(--accent-text) !important; }
#plan-period-toggle button b { font-size: 16px !important; }

.goal-templates { gap: var(--space-3); }
.goal-template-card { display: flex; align-items: flex-start; gap: var(--space-3); transition: border-color var(--motion-fast) var(--ease-standard), box-shadow var(--motion-fast) var(--ease-standard); }
.goal-template-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-2); }
.goal-template-card::before {
  content: "💧"; flex: none; width: 40px; height: 40px; border-radius: 12px; background: var(--accent-soft);
  display: flex; align-items: center; justify-content: center; font-size: 18px;
}

.goal-status-pill { letter-spacing: .02em; }
.goal-waterline { box-shadow: inset 0 1px 2px rgba(11,35,68,.08); }

/* ==========================================================================
   BOTTOM NAVIGATION — restored as PRIMARY navigation at every viewport,
   evolved into a premium floating dock rather than pasted back unchanged.
   Human feedback: top nav was a usability regression; the + belongs at the
   bottom within thumb reach, on desktop too — no detached sidebar.
   ========================================================================== */
.bottom-nav {
  bottom: max(14px, env(safe-area-inset-bottom)) !important;
  border-top: none !important;
  border: 1px solid var(--border-subtle) !important;
  border-radius: 24px !important;
  box-shadow: var(--shadow-3) !important;
  padding: 8px 6px calc(8px + env(safe-area-inset-bottom)) !important;
  position: fixed !important;
}
.bottom-nav-7 { grid-template-columns: repeat(7,1fr) !important; }
.bottom-nav button { position: relative; z-index: 1; transition: color var(--motion-ui) var(--ease-standard); min-width: 0; }
.bottom-nav button span { font-size: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
.bottom-nav button b { display: flex; align-items: center; justify-content: center; }
.bottom-nav button b svg { width: 21px; height: 21px; display: block; }
.nav-indicator {
  position: absolute; top: 6px; bottom: 6px; left: 0; width: 60px; border-radius: 16px; z-index: 0;
  background: var(--accent-soft); pointer-events: none;
  transition: transform var(--motion-ui) var(--ease-fluid), width var(--motion-ui) var(--ease-fluid), opacity var(--motion-fast) var(--ease-standard);
  opacity: 0;
}
.nav-indicator.ready { opacity: 1; }

/* v18.6 — active-tab micro-interaction: icon lift + scale + soft accent glow.
   Color transition already existed (.bottom-nav button, above); this adds the
   icon-level feedback on top of it, same --motion-ui timing (210ms, inside
   the 180-300ms brief target). Theme-safe: uses var(--accent), so it adapts
   automatically across Light/Dark/Pink without a per-theme override. */
.bottom-nav button b svg { transition: transform var(--motion-ui) var(--ease-fluid), filter var(--motion-ui) var(--ease-standard); }
.bottom-nav button.active b svg { transform: translateY(-2px) scale(1.08); filter: drop-shadow(0 3px 7px color-mix(in srgb, var(--accent) 45%, transparent)); }

/* Icon-only compact mode — 7 destinations must never mean cramped labels.
   Below 431px the label disappears entirely (not truncated/tiny), icons and
   the sliding indicator carry identity, touch targets stay full-height. */
@media (max-width: 430.98px) {
  :root { --dock-height: 56px; }
  .bottom-nav-7 button span { display: none; }
  .bottom-nav-7 button b svg { width: 23px; height: 23px; }
  .bottom-nav-7 { padding-left: 4px !important; padding-right: 4px !important; }
}

@media (min-width: 431px) and (max-width: 1079.98px) {
  :root { --dock-height: 68px; }
}

@media (min-width: 1080px) {
  :root { --dock-height: 74px; --dock-breathing: 26px; }
  .app { max-width: 760px; }
  .summary-grid { grid-template-columns: repeat(4,1fr); }
  .quick-grid { grid-template-columns: repeat(4,1fr); }
  .goal-stat-grid { grid-template-columns: repeat(4,1fr); }
  .modal { align-items: center; }
  .sheet { border-radius: var(--radius-modal) !important; max-width: 520px; }
  /* Premium centered dock, not a full-width bar and not a sidebar */
  .bottom-nav { width: min(600px,94%) !important; padding: 10px 8px calc(10px + env(safe-area-inset-bottom)) !important; }
  .bottom-nav button span { display: block; font-size: 12px; }
  .bottom-nav button b svg { width: 20px; height: 20px; }
}
@media (min-width: 768px) and (max-width: 1079.98px) {
  .app { max-width: 680px; padding-left: 20px; padding-right: 20px; }
  .bottom-nav { width: min(560px,94%) !important; }
  .bottom-nav button span { font-size: 10px; }
  .summary-grid { grid-template-columns: repeat(4,1fr); }
  .quick-grid { grid-template-columns: repeat(4,1fr); }
  .goal-stat-grid { grid-template-columns: repeat(4,1fr); }
}

/* ==========================================================================
   PAGE TRANSITIONS — real, JS-sequenced (a plain opacity transition cannot
   play across a display:none swap, so page() adds .page-enter for one frame
   before removing it; see app.js).
   ========================================================================== */
.page.active { transition: opacity var(--motion-ui) var(--ease-fluid), transform var(--motion-ui) var(--ease-fluid); }
.page.active.page-enter { opacity: 0 !important; transform: translateY(8px); transition: none !important; }

/* ==========================================================================
   DASHBOARD ENTRANCE — summary-card stagger, triggered only on genuine
   navigation to the home page (see triggerHomeEntrance() in app.js), never
   on a background refresh.
   ========================================================================== */
.stagger-enter .summary-grid > * { opacity: 0; transform: translateY(4px); animation: su-stagger-in var(--motion-ui) var(--ease-standard) forwards; }
.stagger-enter .summary-grid > *:nth-child(1) { animation-delay: 0ms; }
.stagger-enter .summary-grid > *:nth-child(2) { animation-delay: 40ms; }
.stagger-enter .summary-grid > *:nth-child(3) { animation-delay: 80ms; }
.stagger-enter .summary-grid > *:nth-child(4) { animation-delay: 120ms; }
@keyframes su-stagger-in { to { opacity: 1; transform: translateY(0); } }

/* ==========================================================================
   BALANCE FLOW CUES — directional confirmation after a save, keyed by
   transaction type. Runs alongside the existing scale pulse.
   ========================================================================== */
@keyframes su-flow-income { 0%{box-shadow:0 0 0 0 rgba(21,122,83,0)} 35%{box-shadow:0 0 0 10px rgba(21,122,83,.20)} 100%{box-shadow:0 0 0 0 rgba(21,122,83,0)} }
@keyframes su-flow-expense { 0%{box-shadow:0 0 0 0 rgba(194,63,63,0)} 35%{box-shadow:0 0 0 10px rgba(194,63,63,.20)} 100%{box-shadow:0 0 0 0 rgba(194,63,63,0)} }
@keyframes su-flow-transfer { 0%{box-shadow:0 0 0 0 rgba(63,111,168,0)} 35%{box-shadow:0 0 0 10px rgba(63,111,168,.20)} 100%{box-shadow:0 0 0 0 rgba(63,111,168,0)} }
#home-hero.su-flow-income { animation: su-flow-income var(--motion-flow) var(--ease-standard); border-radius: inherit; }
#home-hero.su-flow-expense { animation: su-flow-expense var(--motion-flow) var(--ease-standard); border-radius: inherit; }
#home-hero.su-flow-transfer { animation: su-flow-transfer var(--motion-flow) var(--ease-standard); border-radius: inherit; }

/* ==========================================================================
   v18.6 — MONEY FEEDBACK — reusable post-save amount confirmation. A single
   fixed element, reused for every transaction form (see showMoneyFeedback()
   in app.js) rather than duplicated per form. Decorative only — the real
   confirmation is the toast/refreshed balances underneath — so aria-hidden.
   Appears only after a genuine backend success; never on failure.
   ========================================================================== */
.money-feedback {
  position: fixed; left: 50%; top: 16%; z-index: 400; pointer-events: none;
  transform: translate(-50%,10px) scale(.92); opacity: 0;
  font-weight: 800; font-size: 19px; letter-spacing: .01em;
  padding: 10px 20px; border-radius: 999px; white-space: nowrap;
  background: var(--surface-1); border: 1px solid var(--border-subtle); box-shadow: var(--shadow-3);
  transition: opacity var(--motion-success) var(--ease-fluid), transform var(--motion-success) var(--ease-fluid);
}
.money-feedback.show { opacity: 1; transform: translate(-50%,0) scale(1); }
.money-feedback.income { color: var(--income); }
.money-feedback.expense { color: var(--expense); }
.money-feedback.transfer { color: var(--transfer); }

/* ==========================================================================
   v18.6 — GOAL COMPLETION — restrained one-shot celebration, triggered only
   when a plan's computed status genuinely transitions to savings_achieved
   this session (see celebrateNewlyCompletedGoals() in app.js). No confetti.
   ========================================================================== */
@keyframes su-goal-celebrate { 0%{ transform: scale(1); } 35%{ transform: scale(1.018); } 100%{ transform: scale(1); } }
@keyframes su-goal-check { 0%{ opacity: 0; transform: translateY(6px) scale(.7); } 25%{ opacity: 1; transform: translateY(0) scale(1.12); } 70%{ opacity: 1; transform: translateY(0) scale(1); } 100%{ opacity: 0; transform: translateY(-3px) scale(1); } }
.goal-card.goal-celebrate { animation: su-goal-celebrate var(--motion-success) var(--ease-fluid); position: relative; }
.goal-card.goal-celebrate::after {
  content: "✓"; position: absolute; top: 12px; right: 16px; font-size: 20px; font-weight: 800;
  color: var(--income); opacity: 0; pointer-events: none;
  animation: su-goal-check var(--motion-success) var(--ease-fluid);
}

/* ==========================================================================
   v18.6 — RECEIPT UPLOAD FEEDBACK — select -> uploading -> success states.
   No fake percentage; "uploading" is an indeterminate state only.
   ========================================================================== */
#transaction-receipt-preview { display: flex; align-items: center; gap: 8px; margin-top: 6px; padding: 8px 12px; border-radius: var(--radius-control); background: var(--surface-2); border: 1px solid var(--border-subtle); font-size: 13px; color: var(--text-secondary); }
#transaction-receipt-preview .receipt-spinner { width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--border-strong); border-top-color: var(--accent); animation: su-spin 700ms linear infinite; flex: none; }
#transaction-receipt-preview.state-success { color: var(--income); }
#transaction-receipt-preview.state-error { color: var(--expense); }
@keyframes su-spin { to { transform: rotate(360deg); } }

/* ==========================================================================
   QUICK-ADD — backdrop fade (keyframe-based so it restarts reliably every
   time the modal re-enters the render tree). The droplet itself stays
   upright on open — only its `+` glyph rotates, see .plus-mark above.
   ========================================================================== */
@keyframes su-backdrop-fade { from { background-color: rgba(4,24,48,0); } to { background-color: rgba(4,24,48,.45); } }
.modal:not(.hidden) { animation: su-backdrop-fade var(--motion-ui) var(--ease-standard); }

/* ==========================================================================
   GOAL STATUS MOTION — one-shot attention pulse, never looping.
   ========================================================================== */
@keyframes su-attention-pulse { 0%{box-shadow:0 0 0 0 rgba(168,114,31,0)} 30%{box-shadow:0 0 0 10px rgba(168,114,31,.16)} 100%{box-shadow:0 0 0 0 rgba(168,114,31,0)} }
.goal-card.pulse-attention { animation: su-attention-pulse 900ms var(--ease-standard); }
.goal-stat.flow b::before { content: "→ "; color: var(--accent); font-weight: 800; }

/* Brand motto — restrained, appears only at genuine brand moments (login),
   never repeated under every page heading. */
.brand-motto { text-align: center; margin: -4px 0 10px; font-size: 13px; letter-spacing: .02em; color: var(--accent-text) !important; font-weight: 600; }

/* ==========================================================================
   VARLIKLARIM — distribution segments + a distinct "value-depth" hero
   treatment (layered translucency instead of the dashboard hero's single
   flow-line), so the two water-identity surfaces read as related but not
   identical (section 9 of the brief).
   ========================================================================== */
.dist-bar { height: 16px; border-radius: 999px; display: flex; overflow: hidden; background: var(--surface-3); margin-bottom: var(--space-3); }
.dist-seg { display: block; height: 100%; }
.dist-cash { background: linear-gradient(90deg,var(--accent-deep),var(--accent)); }
.dist-metal { background: linear-gradient(90deg,#8a6a1f,#c9a227); }
.dist-inv { background: linear-gradient(90deg,#0c5c3f,var(--income)); }
.dist-rec { background: linear-gradient(90deg,#3f6fa8,var(--accent-2)); }
#assets-hero::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(255,255,255,.16) 0%, rgba(255,255,255,.04) 45%, transparent 70%);
  animation: none;
}
#assets-hero .hero-waterline { bottom: 24%; }

/* ==========================================================================
   REDUCED MOTION — full functional parity, near-instant transitions
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .hero::before { animation: none !important; display: none; }
  .primary::after,.central-add::after { transition: none !important; }
  .card.premium::after { transition: none !important; }
  .su-value-changed { animation: none !important; }
  .goal-waterline > span,.hero-waterline { transition: none !important; }
  .page,.page.active { transition: none !important; }
  .page.active.page-enter { opacity: 1 !important; transform: none !important; }
  .modal .sheet { animation: none !important; }
  .modal:not(.hidden) { animation: none !important; background-color: rgba(4,24,48,.45) !important; }
  .toast { transition: opacity 1ms linear !important; }
  .stagger-enter .summary-grid > * { animation: none !important; opacity: 1 !important; transform: none !important; }
  #home-hero.su-flow-income,#home-hero.su-flow-expense,#home-hero.su-flow-transfer { animation: none !important; }
  .central-add { transition: none !important; }
  .goal-card.pulse-attention { animation: none !important; }
  .nav-indicator { transition: none !important; }
  .auth-tab-indicator { transition: none !important; }
  .auth-card { animation: none !important; }
  *{ scroll-behavior: auto !important; }

  /* v18.6 additions — decorative motion removed, state feedback kept instant */
  .bottom-nav button b svg { transition: none !important; }
  .money-feedback { transition: opacity 1ms linear !important; }
  .goal-card.goal-celebrate { animation: none !important; }
  .goal-card.goal-celebrate::after { animation: none !important; opacity: 1 !important; }
  #transaction-receipt-preview .receipt-spinner { animation: none !important; }
  .auth-logo-plate .auth-ripple::before,.auth-logo-plate .auth-ripple::after { animation: none !important; display: none; }
  #cloud-auth.auth-mode-switch { animation: none !important; }
  .auth-card.auth-shake { animation: none !important; }
  body.auth-success-transition #loading::before { animation: none !important; display: none; }
}

/* ==========================================================================
   AUTH REDESIGN — v18.2 premium login/register/reset experience. Mobile
   stays a single focused card (brief section 3: "Family SU is an app
   first"); >=1080px gains a restrained second pane reusing the existing
   .hero water-gradient + waterline + droplet geometry (brief section 33/34
   coherence requirement), not a marketing landing page.
   ========================================================================== */
.auth-shell { width: 100%; display: flex; justify-content: center; }
.auth-brand-panel { display: none; }
.auth-topbar { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 14px; }
.auth-lang-toggle,.auth-theme-toggle { display: flex; gap: 2px; background: var(--surface-2); border: 1px solid var(--border-subtle); border-radius: 999px; padding: 3px; }
.auth-lang-btn,.auth-theme-btn { border: 0; background: transparent; border-radius: 999px; padding: 6px 10px; color: var(--text-secondary); font-size: 12px; font-weight: 700; line-height: 1; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: background var(--motion-fast) var(--ease-standard), color var(--motion-fast) var(--ease-standard); }
.auth-theme-btn { padding: 6px; width: 28px; height: 28px; }
.auth-theme-btn svg { width: 15px; height: 15px; }
.auth-lang-btn.active,.auth-theme-btn.active { background: var(--surface-1); color: var(--accent-text); box-shadow: var(--shadow-1); }
.profile-theme-row { display: flex; justify-content: space-between; align-items: center; border: 1px solid var(--border-subtle); background: var(--surface-1); border-radius: 16px; padding: 10px 14px; color: var(--text-primary); }
.profile-theme-label { font-size: 15px; }
.profile-theme-row .auth-theme-toggle { background: var(--surface-2); }
.profile-theme-row select { margin: 0; width: auto; border: 1px solid var(--border-subtle); border-radius: 10px; padding: 6px 10px; background: var(--surface-2); color: var(--text-primary); }
#applock-screen .auth-card { text-align: center; }

/* Backup/restore modal (v18.3) — replaces the bare browser file input with a
   restyled real <input type="file"> (::file-selector-button), no hidden-input
   JS hack, full native accessibility/keyboard support preserved. */
.backup-block { border: 1px solid var(--border-subtle); background: var(--surface-2); border-radius: var(--radius-card); padding: var(--space-4); margin-bottom: var(--space-3); }
.backup-block-head { display: flex; gap: var(--space-3); align-items: flex-start; margin-bottom: var(--space-3); }
.backup-icon { font-size: 22px; line-height: 1; flex: none; }
.backup-block-head h3 { margin: 0 0 3px; font-size: 15px; }
.backup-block-head p { margin: 0; color: var(--text-secondary); font-size: 13px; line-height: 1.4; }
.backup-note { margin: var(--space-3) 0 0; color: var(--text-tertiary); font-size: 12px; line-height: 1.4; }
input.file-input { width: 100%; padding: 10px; border: 1px dashed var(--border-strong); border-radius: var(--radius-control); background: var(--surface-1); color: var(--text-secondary); font-size: 13px; }
input.file-input::file-selector-button {
  border: 0; background: var(--accent-soft); color: var(--accent-text); font-weight: 700; font-size: 13px;
  border-radius: 10px; padding: 9px 14px; margin-right: 12px; cursor: pointer;
  transition: background var(--motion-fast) var(--ease-standard);
}
input.file-input:hover::file-selector-button,
input.file-input:focus-visible::file-selector-button { background: var(--surface-3); }
input.file-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.auth-logo-plate { width: 88px; height: 88px; margin: 0 auto 14px; border-radius: 24px; overflow: hidden; background: var(--surface-2); border: 1px solid var(--border-subtle); box-shadow: var(--shadow-1); display: flex; align-items: center; justify-content: center; }
.auth-logo-plate .auth-logo { width: 100%; height: 100%; margin: 0; object-fit: cover; display: block; }
.auth-card h1 { font-size: 22px; }
.motto-en { display: none; }
html[lang="en"] .motto-en { display: block; }
html[lang="en"] .motto-tr { display: none; }
.auth-tabs { position: relative; background: var(--surface-2); border-radius: var(--radius-control); padding: 4px; border: 1px solid var(--border-subtle); }
.auth-tabs button { position: relative; z-index: 1; background: transparent !important; border: 0 !important; }
#auth-screen .auth-tabs button.active { background: transparent !important; }
.auth-tab-indicator { position: absolute; top: 4px; bottom: 4px; left: 4px; border-radius: calc(var(--radius-control) - 3px); background: color-mix(in srgb, var(--surface-1) 100%, var(--text-primary) 10%); border: 1px solid var(--border-strong); box-shadow: var(--shadow-2); z-index: 0; transition: transform var(--motion-ui) var(--ease-fluid), width var(--motion-ui) var(--ease-fluid); }
.auth-password-wrap { position: relative; display: block; margin-top: 6px; }
.auth-password-wrap input { margin-top: 0 !important; padding-right: 44px !important; }
.password-toggle { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); width: 32px; height: 32px; border: 0; background: transparent; color: var(--text-secondary); display: flex; align-items: center; justify-content: center; border-radius: 10px; cursor: pointer; }
.password-toggle:hover { background: var(--surface-3); }
.password-toggle svg { width: 18px; height: 18px; }
.auth-card input:focus-visible,.auth-card select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.auth-card input:invalid:not(:placeholder-shown):not(:focus) { border-color: color-mix(in srgb, var(--danger) 45%, var(--border-subtle)) !important; }

@keyframes su-auth-reveal { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
.auth-card { animation: su-auth-reveal var(--motion-slow) var(--ease-fluid); }

/* v18.7: desktop keeps the single focused login card (no second brand pane) — same as mobile. */
@media (min-width: 1080px) {
  .auth-card { max-width: 460px; width: 100%; }
}


/* ==========================================================================
   v18.6 — AUTH RETURNING/NEW-USER GATE — the auth screen's first moment now
   asks one question (returning or new) instead of opening straight into a
   login form. #auth-gate shows first; picking either option reveals
   #cloud-auth (the existing form, unchanged fields/validation/behavior)
   already set to the matching mode. Navigation choice only — no enumeration
   signal is introduced anywhere in this flow (see authSubmit()/app.js).
   ========================================================================== */
.auth-heading { text-align: center; font-size: 19px; font-weight: 800; margin: 4px 0 16px; color: var(--text-primary); }
.auth-switch-line { text-align: center; font-size: 13px; color: var(--text-secondary); margin: 14px 0 0; }
.auth-switch-line .text-button { font-weight: 800; padding: 0 0 0 4px; }
.auth-back { display: block; margin: 10px auto 0; font-size: 12px; color: var(--text-tertiary) !important; }
#auth-gate .primary { margin-bottom: 4px; }

/* Subtle water-identity ripple under the logo — original interpretation
   (concentric expanding rings, faint, one-shot on screen entry), not a copy
   of any third-party asset. Decorative -> aria-hidden, ignored by AT. */
.auth-logo-plate { position: relative; overflow: visible; }
.auth-logo-plate .auth-ripple { position: absolute; inset: 0; border-radius: inherit; pointer-events: none; }
.auth-logo-plate .auth-ripple::before,
.auth-logo-plate .auth-ripple::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  border: 1.5px solid color-mix(in srgb, var(--accent) 55%, transparent);
  opacity: 0; animation: su-auth-ripple 2400ms var(--ease-standard) 1;
}
.auth-logo-plate .auth-ripple::after { animation-delay: 260ms; }
@keyframes su-auth-ripple { 0%{ transform: scale(1); opacity: .55; } 100%{ transform: scale(1.55); opacity: 0; } }

/* Sign-in/sign-up switch — a soft cross-fade instead of a hard swap, the
   "liquid transition" called for in the brief, kept cheap (opacity/transform
   only, per Part 17). */
@keyframes su-auth-form-in { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: translateY(0); } }
#cloud-auth.auth-mode-switch { animation: su-auth-form-in var(--motion-normal) var(--ease-fluid); }

/* Login failure — very subtle shake, never on the gate/switch action itself,
   only on a real rejected credential attempt (see authSubmit()). */
@keyframes su-auth-shake { 10%,90%{ transform: translateX(-1px); } 20%,80%{ transform: translateX(2px); } 30%,50%,70%{ transform: translateX(-4px); } 40%,60%{ transform: translateX(4px); } }
.auth-card.auth-shake { animation: su-auth-shake 420ms var(--ease-standard); }

/* Login success — a brief branded wave over the loading screen, capped at
   ~700ms by app.js (setTimeout), never gating the real async loadCloud()
   work happening underneath it in parallel. */
@keyframes su-success-wave { 0%{ opacity: 0; transform: scale(.85); } 40%{ opacity: .5; } 100%{ opacity: 0; transform: scale(1.4); } }
body.auth-success-transition #loading::before {
  content: ""; position: fixed; inset: 0; margin: auto; width: 140px; height: 140px; border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent) 35%, transparent) 0%, transparent 70%);
  animation: su-success-wave 700ms var(--ease-fluid) 1; pointer-events: none;
}

/* v18.7 — bill reminders: due chips, warning states, banner */
.due-banner { margin: 0 0 10px; padding: 12px 14px; border-radius: 14px; font-weight: 700; font-size: 14px;
  background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--text-primary);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); }
.due-row .due-actions { display: flex; align-items: center; gap: 10px; }
.due-chip { font-weight: 700; }
.due-soon .due-chip { color: #b26a00; }
.due-late .due-chip { color: #c0362c; }
[data-theme="dark"] .due-soon .due-chip { color: #ffb84d; }
[data-theme="dark"] .due-late .due-chip { color: #ff8078; }

/* v18.7.1 opt-in checkbox row (statement panel) */
.check-row{display:flex!important;align-items:center;gap:8px}
.check-row input{width:auto!important;margin:0!important}

/* v18.7.5 app lock: real full-screen overlay; hide app content while locked */
#applock-screen{position:fixed;inset:0;z-index:10000;background:var(--bg,#fff)}
html.applock-on #app,html.applock-on .modal,html.applock-on .bottom-nav{visibility:hidden}

/* v18.7.6 statement panel layout */
#statement-panel .statement-disclosure{font-size:12px;line-height:1.45;margin:10px 2px 12px}
#statement-panel .check-row{padding:13px 14px;border-radius:14px;border:1px solid color-mix(in srgb,var(--text-secondary,#5b6b82) 28%,transparent);font-weight:650;font-size:14px}
.stmt-meta{display:grid;gap:4px;padding:12px 14px;margin:12px 0 0;border-radius:14px;background:var(--accent-soft,#edf6ff);color:var(--text-secondary,#41617f);font-size:13px;line-height:1.4}
.stmt-meta b{color:var(--text-primary,inherit);word-break:break-all}
.stmt-meta .stmt-status:empty{display:none}
.stmt-actions{display:grid;gap:10px;margin-top:16px}
.stmt-actions button{margin-top:0}

/* v18.7.11 — iPhone/Safari: form alanları 16px'in altındaysa sayfa dokununca otomatik yakınlaşır (ve geri küçülmez).
   Alanları 16px yaparak bunu engelliyoruz; çift dokunma yakınlaştırmasını da kapatıyoruz. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]),
select, textarea { font-size: 16px; }
input, select, textarea, button, a { touch-action: manipulation; }

/* v18.7.13 — bottom nav: sabit damla + iki yanda kaydırılabilir şerit (sürükleyince diğer sekmeler görünür) */
.bottom-nav.bottom-nav-7 { display: grid !important; grid-template-columns: minmax(0,1fr) 64px minmax(0,1fr) !important; align-items: end; gap: 0 !important; padding: 6px 0 calc(8px + env(safe-area-inset-bottom)) 0 !important; }
.bottom-nav-7 .nav-lane { display: flex; position: relative; min-width: 0; max-width: 100%; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; scrollbar-width: none; -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain; align-self: stretch; }
.bottom-nav-7 .nav-lane::-webkit-scrollbar { display: none; }
.bottom-nav-7 .nav-lane button { flex: 0 0 43%; min-width: 64px; scroll-snap-align: start; padding: 6px 2px; }
.bottom-nav-7 .nav-lane button span { display: block !important; font-size: 10px; margin-top: 2px; }
.bottom-nav-7 .nav-lane button b svg { width: 22px; height: 22px; }
.bottom-nav-7 .central-add { justify-self: center; align-self: end; }
.bottom-nav-7 .nav-indicator { display: none !important; }
/* kenardaki yarım sekmeyi damla tarafında yumuşakça sil (yalnızca o yönde gizli sekme varken) */
.bottom-nav-7 .nav-lane-left.has-more { -webkit-mask-image: linear-gradient(to right, #000 74%, transparent 100%); mask-image: linear-gradient(to right, #000 74%, transparent 100%); }
.bottom-nav-7 .nav-lane-right.has-more { -webkit-mask-image: linear-gradient(to right, transparent 0, #000 26%); mask-image: linear-gradient(to right, transparent 0, #000 26%); }

/* v18.7.13 — yatay lastik/taşma yok: sayfa yalnızca dikey kayar; yatay kaydırma yalnızca alt menü şeritlerinde ve kaydırılabilir kartlarda */
html, body { max-width: 100%; overflow-x: clip; overscroll-behavior-x: none; }
body { touch-action: pan-y pinch-zoom; }
.bottom-nav-7 .nav-lane { touch-action: pan-x; }
.app, .page, main { max-width: 100%; }

/* v18.7.13 — aşağı/yukarı çekince beyaz boşluk yok: lastik (overscroll) kapalı, sayfa dışı zemin temayla aynı renk */
html, body { overscroll-behavior: none; }
html { background-color: #f4f8fc; }
:root[data-theme="dark"] { background-color: #100d1e; }
:root[data-theme="purple"] { background-color: #fdf7f9; }
body { min-height: 100vh; min-height: 100dvh; }
