/* ==========================================================================
   MacLaine Finance, Field & Input Component System
   fields.css  ·  v1.0
   --------------------------------------------------------------------------
   A modular, bilingual, theme-aware set of form-field components. Every tool
   composes its input UI (and the shared "Your Details" section) from these
   classes. Add or remove fields freely, the group grid reflows on its own.

   DEPENDS ON  _shared.css design tokens. Load this file AFTER _shared.css:
       <link rel="stylesheet" href="/finance/_shared.css">
       <link rel="stylesheet" href="/finance/fields.css">

   Tokens consumed (all already defined in _shared.css, light + dark):
       --bg --surface --surface-2 --ink --muted --faint
       --line --line-2 --accent --accent-soft --accent-text --red --red-soft
       --radius --sans --mono --serif
   Dark theme is driven by [data-theme="dark"] on <html> (same as _shared.css).
   Nothing here redefines a colour token, restyle the whole system by editing
   _shared.css.

   INTENTIONAL #fff EXCEPTION: three surfaces are hard white in light mode by
   design, the free-input well (.fld__input), the switch knob
   (.switch__track::after) and the stepper track (.stepper). They read as
   "type/act here" against the warm --surface card, and each has a correct
   [data-theme="dark"] override. This is the suite's only sanctioned raw-#fff
   use; do not "tokenise" it away.

   A11Y (intake, 0.24): every interactive control carries :focus-visible; the
   segmented toggle mirrors its state in aria-pressed (the controller sets both
   the .is-on class and aria-pressed, and this file styles both), so toggle
   state is programmatic, not class-only. prefers-reduced-motion is handled by
   the global kill switch in _shared.css (loaded first, `*` + !important), which
   reaches every transition below, nothing to duplicate here.

   CONTENTS
     1  Density scale ............ --fld-* vars + .fields--compact
     2  Field primitive .......... .fld  .fld__label  .fld__control  .fld__input
     3  Input variants ........... --suffix  --select  --computed
     4  Choice controls .......... .seg  .switch  .stepper  .range
     5  States & affordances ..... :focus  .is-default  .fld--inherited
                                    .fld__hint  .tip  .fld--error
     6  Groups & layout .......... .fgroup  .fgrid
     7  Person / partner ......... .people  .person  .addcard  .sharednote
        Input enclosure .......... .fcard  (bounded surface for a tool input section)
     8  Modifiers ................ .fields--compact  .fields--uppercase
   ========================================================================== */


/* 1 ── DENSITY SCALE ──────────────────────────────────────────────────────
   Three spacing values drive the whole system. Comfortable is the default
   (full-page tool sections). Add .fields--compact on any wrapper to tighten
   for dense contexts, this is what the settings-drawer sub-page uses. */
:root{
  --fld-card-pad:   1.6rem 1.85rem;   /* .person padding                     */
  --fld-group-gap:  1.9rem;           /* space above each .fgroup            */
  --fld-grid-gap:   1.05rem 1.3rem;   /* row/col gap between fields in .fgrid */
  --fld-col-min:    185px;            /* min field width before the grid wraps */
}
.fields--compact{
  --fld-card-pad:   1.05rem 1.25rem;
  --fld-group-gap:  1.2rem;
  --fld-grid-gap:   .85rem 1rem;
  --fld-col-min:    100%;             /* drawer is narrow → always one column */
}


/* 2 ── FIELD PRIMITIVE ────────────────────────────────────────────────────
   The atom of the system. Every field is:
       .fld > .fld__label + .fld__control > .fld__input
   Labels are sentence-case sans (readable); reserve UPPERCASE MONO for group
   headings so hierarchy reads through case + typeface, not size alone. */
.fld{ display:flex; flex-direction:column; min-width:0; }
.fld__label{
  font-family:var(--sans); font-size:12.5px; font-weight:500; letter-spacing:0;
  color:var(--ink); margin-bottom:.5rem; line-height:1.35;
}
.fld__control{ position:relative; }

.fld__input{
  display:block; width:100%;
  background:#fff; border:1px solid var(--line); border-radius:var(--radius);
  color:var(--ink); font-family:var(--mono); font-size:13px;
  padding:.65rem .9rem; min-height:44px;                 /* 44px touch target */
  outline:none; -webkit-appearance:none; appearance:none;
  transition:border-color .2s, background .2s;
}
.fld__input:focus{ border-color:var(--accent); }        /* focus affordance   */
.fld__input::-webkit-outer-spin-button,
.fld__input::-webkit-inner-spin-button{ -webkit-appearance:none; margin:0; }
.fld__input[type=number]{ -moz-appearance:textfield; }
[data-theme="dark"] .fld__input{ background:var(--surface); }


/* 3 ── INPUT VARIANTS ─────────────────────────────────────────────────────
   FREE INPUTS  are white (light) / surface (dark) → "type here".
   DROPDOWNS    get a surface-2 tint + a caret → "choose from a list".
   This tint/caret contrast is the primary affordance that tells the two apart. */

/* 3a  --suffix : a trailing unit inside the box (currency, %, age). */
.fld__control--suffix .fld__input{ padding-right:2.6rem; }
.fld__unit{
  position:absolute; right:.9rem; top:50%; transform:translateY(-50%);
  font-family:var(--mono); font-size:12px; color:var(--faint); pointer-events:none;
}

/* 3b  --select : a native <select>. Wrap it in .fld__control--select for the caret. */
.fld__input--select{
  background:var(--surface-2); cursor:pointer; padding-right:2.4rem;
  -webkit-appearance:none; appearance:none;
}
[data-theme="dark"] .fld__input--select{ background:var(--surface-2); }
.fld__control--select::after{                               /* CSS caret */
  content:''; position:absolute; right:.95rem; top:50%; transform:translateY(-50%);
  width:0; height:0; pointer-events:none;
  border-left:4px solid transparent; border-right:4px solid transparent;
  border-top:5px solid var(--faint);
}

/* 3c  --computed : a derived, read-only value (e.g. annual = monthly × 12).
   Dashed border + muted text signal "not editable, calculated for you". */
.fld__input--computed{
  background:var(--surface-2); color:var(--muted);
  border-style:dashed; cursor:default;
}
[data-theme="dark"] .fld__input--computed{ background:var(--surface-2); }


/* 4 ── CHOICE CONTROLS ────────────────────────────────────────────────────
   Never use a dropdown for a small fixed choice. Pick by intent:
     .seg      2–3 mutually-exclusive DATA options (Yes/No, Low/Med/High)
     .switch   an on/off BEHAVIOUR flag (include in projection, notify me)
     .stepper  a small integer you nudge (children, dependents)
     .range    a continuous value with a live readout (rate, %) */

/* 4a  Segmented toggle, replaces the yes/no dropdown, and scales to N options. */
.seg{
  display:flex; width:100%; gap:3px; min-height:44px; padding:3px;
  background:var(--surface-2); border:1px solid var(--line); border-radius:var(--radius);
}
.seg__opt{
  flex:1; font-family:var(--mono); font-size:12px; letter-spacing:.02em;
  color:var(--faint); background:none; border:none; border-radius:3px;
  padding:0 12px; cursor:pointer; transition:all .2s;
}
.seg__opt.is-on,
.seg__opt[aria-pressed="true"]{ background:var(--ink); color:var(--bg); }   /* neutral ink fill, both themes */
.seg__opt:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

/* 4b  Switch, CSS-only on/off. Markup: label.switch > input[checkbox] + span.switch__track */
.switch{ display:inline-flex; align-items:center; gap:.65rem; min-height:44px; cursor:pointer; }
.switch input{ position:absolute; opacity:0; width:0; height:0; }
.switch__track{
  position:relative; flex:0 0 auto; width:46px; height:26px; border-radius:999px;
  background:var(--surface-2); border:1px solid var(--line);
  transition:background .2s, border-color .2s;
}
.switch__track::after{
  content:''; position:absolute; top:2px; left:2px; width:20px; height:20px;
  border-radius:50%; background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.2);
  transition:transform .2s;
}
.switch input:checked + .switch__track{ background:var(--accent); border-color:var(--accent); }
.switch input:checked + .switch__track::after{ transform:translateX(20px); }
.switch input:focus-visible + .switch__track{ outline:2px solid var(--accent); outline-offset:2px; }
.switch__txt{ font-family:var(--mono); font-size:12px; color:var(--muted); }

/* 4c  Stepper, −/value/+ for small integers. */
.stepper{
  display:flex; align-items:center; width:100%; min-height:44px; overflow:hidden;
  background:#fff; border:1px solid var(--line); border-radius:var(--radius);
}
[data-theme="dark"] .stepper{ background:var(--surface); }
.stepper__btn{
  width:44px; flex:0 0 auto; min-height:42px;
  font-family:var(--mono); font-size:18px; line-height:1; color:var(--faint);
  background:none; border:none; cursor:pointer; transition:color .2s, background .2s;
}
.stepper__btn:hover{ color:var(--accent); background:var(--accent-soft); }
.stepper__btn:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px; }
.stepper__val{ flex:1; text-align:center; font-family:var(--mono); font-size:13px; color:var(--ink); }

/* 4d  Range slider, a continuous value + right-aligned readout. */
.range{ display:flex; align-items:center; gap:.9rem; min-height:44px; }
.range input[type=range]{
  flex:1; -webkit-appearance:none; appearance:none; height:4px; border-radius:999px;
  background:var(--surface-2); outline:none; cursor:pointer;
}
.range input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none; width:18px; height:18px; border-radius:50%;
  background:var(--accent); border:2px solid var(--bg); cursor:pointer;
  box-shadow:0 1px 4px rgba(0,0,0,.15);
}
.range input[type=range]::-moz-range-thumb{
  width:18px; height:18px; border-radius:50%; background:var(--accent);
  border:2px solid var(--bg); cursor:pointer;
}
.range__val{
  flex:0 0 auto; min-width:52px; text-align:right;
  font-family:var(--mono); font-size:13px; color:var(--accent-text);
}


/* 5 ── STATES & AFFORDANCES ───────────────────────────────────────────────
   focus ....... accent border (see .fld__input:focus above)
   default ..... .is-default → muted text: value is a suggested default, not
                 user-entered. JS should drop the class on first user edit.
   inherited ... .fld--inherited → this value came from the SHARED store
                 (set in another tool). Subtle accent tint + a .fld__origin tag.
                 THE FRAMEWORK'S SUPERPOWER, make it visible. Toggle the class
                 off (and the tag) once the user overrides the value locally. */
.fld__input.is-default{ color:var(--muted); }

/* Tag-only (owner/principal decision, 0.24): the "● Shared" origin tag on the
   label carries the "flowed from your profile" meaning. The full-control tint
   was dropped, after a first visit every value lives in storage, so a
   wall-to-wall tint read as "something is wrong" rather than as provenance.
   The tag is the signal; keep .fld--inherited as the (now paint-free) hook. */
.fld__origin{
  display:inline-flex; align-items:center; gap:.28rem; margin-left:.45rem;
  vertical-align:middle;
  font-family:var(--mono); font-size:9px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--accent-text);
}
.fld__origin::before{ content:''; flex:0 0 auto; width:5px; height:5px; border-radius:50%; background:var(--accent); }

/* 5a  Helper text, a quiet clarifier under the control. */
.fld__hint{
  font-family:var(--mono); font-size:10px; letter-spacing:.02em;
  color:var(--faint); margin-top:.45rem; line-height:1.55;
}

/* 5b  Info tip, a "?" in the label that reveals a definition on hover/focus. */
.tip{ position:relative; display:inline-flex; margin-left:.35rem; vertical-align:middle; }
.tip__mark{
  display:inline-flex; align-items:center; justify-content:center;
  width:14px; height:14px; border-radius:50%; border:1px solid var(--line-2);
  color:var(--faint); font-family:var(--mono); font-size:9px; line-height:1; cursor:help;
}
.tip:hover .tip__mark,
.tip:focus-within .tip__mark{ color:var(--accent); border-color:var(--accent); }
.tip__body{
  position:absolute; left:0; bottom:calc(100% + 7px); z-index:5; width:210px;
  background:var(--surface); border:1px solid var(--line-2); border-radius:var(--radius);
  padding:.6rem .7rem; box-shadow:0 2px 18px rgba(120,90,30,.10);
  font-family:var(--sans); font-size:11px; font-weight:400; line-height:1.5;
  letter-spacing:0; text-transform:none; color:var(--muted);
  opacity:0; visibility:hidden; transform:translateY(4px); pointer-events:none;
  transition:opacity .15s, transform .15s, visibility .15s;
}
.tip:hover .tip__body,
.tip:focus-within .tip__body{ opacity:1; visibility:visible; transform:translateY(0); }

/* 5c  Error state, red border + message. Add .fld--error on the .fld. */
.fld--error .fld__input{ border-color:var(--red); }
.fld__req{ color:var(--accent); margin-left:.15rem; }        /* required asterisk */
.fld__error{
  display:flex; align-items:center; gap:.4rem; margin-top:.45rem;
  font-family:var(--mono); font-size:10px; letter-spacing:.02em; color:var(--red);
}
.fld__error span{                                            /* the "!" badge */
  display:inline-flex; align-items:center; justify-content:center;
  width:13px; height:13px; border-radius:50%;
  background:var(--red); color:var(--surface); font-size:9px; flex:0 0 auto;
}


/* 6 ── GROUPS & LAYOUT ────────────────────────────────────────────────────
   A .fgroup is a labelled cluster of related fields. The .fgrid inside is a
   self-reflowing auto-fit grid: it fills the available width with as many
   --fld-col-min columns as fit, then drops to fewer, no media queries, no
   redesign when you add or remove a field, at any container width. */
.fgroup{ margin-top:var(--fld-group-gap); }
.fgroup:first-child{ margin-top:0; }
.fgroup__label{
  font-family:var(--mono); font-size:10px; letter-spacing:.15em; text-transform:uppercase;
  color:var(--accent-text); padding-bottom:.55rem; margin-bottom:1.05rem;
  border-bottom:1px solid var(--line);
}
.fgrid{
  display:grid; gap:var(--fld-grid-gap);
  grid-template-columns:repeat(auto-fit, minmax(min(100%, var(--fld-col-min)), 1fr));
  align-items:end;   /* keep inputs aligned when one label wraps to 2 lines */
}


/* 7 ── PERSON / PARTNER ───────────────────────────────────────────────────
   The household primitive. Each person is a self-contained CARD. One person =
   one full-width card + a dashed "add partner" ghost that lives in the same
   grid (its scope is unmistakable). Two people = two side-by-side cards; the
   partner card owns its own remove control in its header. */
/* .fcard, the input-area ENCLOSURE for a tool's own input section. Same bounded
   surface as the .person card (surface bg, hairline, radius, card padding) minus
   the person-header semantics: wrap a converted input section in it so the
   labeled groups sit on a bounded surface instead of floating on the page bg.
   The section-label/heading stay OUTSIDE the card, as with the identity panel. */
.fcard{
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius);
  padding:var(--fld-card-pad);
}

.people{ display:grid; gap:1.25rem; grid-template-columns:1fr; }
.people.is-partnered{ grid-template-columns:1fr 1fr; }
@media (max-width:820px){ .people.is-partnered{ grid-template-columns:1fr; } }

.person{
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius);
  padding:var(--fld-card-pad);
}
.person__head{
  display:flex; align-items:center; justify-content:space-between; gap:1rem;
  padding-bottom:1rem; margin-bottom:var(--fld-group-gap); border-bottom:1px solid var(--line);
}
.person__id{ display:flex; align-items:center; gap:.6rem; }
.person__dot{ flex:0 0 auto; width:9px; height:9px; border-radius:50%; background:var(--accent); }
.person__dot--partner{ background:transparent; border:1.5px solid var(--accent); }  /* outline = 2nd entity */
.person__name{ font-family:var(--sans); font-size:16px; font-weight:600; letter-spacing:-.01em; color:var(--ink); }
[data-theme="dark"] .person__name{ font-family:var(--serif); font-weight:400; font-size:20px; }
.person__remove{
  display:inline-flex; align-items:center; gap:.4rem; white-space:nowrap;
  font-family:var(--mono); font-size:10px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--faint); background:none; border:1px solid var(--line); border-radius:var(--radius);
  padding:7px 11px; cursor:pointer; transition:all .2s;
}
.person__remove:hover{ color:var(--red); border-color:var(--red); }
.person__remove:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

/* Add-partner ghost, dashed, sits in the .people grid so it reads as "a slot
   for a second person here", not a floating global button. */
.addcard{
  display:flex; align-items:center; justify-content:center; gap:.85rem; width:100%;
  min-height:96px; padding:1.1rem; text-align:left;
  background:none; border:1.5px dashed var(--line-2); border-radius:var(--radius);
  cursor:pointer; transition:all .2s;
}
.addcard:hover{ border-color:var(--accent); background:var(--accent-soft); }
.addcard:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; border-color:var(--accent); }
/* [hidden] must beat .addcard's display:flex, or the ghost card stays visible in
   partner mode (the attribute alone loses the cascade to the class). */
.addcard[hidden]{ display:none; }
.addcard__plus{ flex:0 0 auto; font-family:var(--mono); font-size:22px; line-height:1; color:var(--accent); }
.addcard__text{ display:flex; flex-direction:column; gap:.2rem; }
.addcard__label{ font-family:var(--sans); font-size:14px; font-weight:600; color:var(--ink); }
.addcard__sub{ font-family:var(--mono); font-size:10px; letter-spacing:.05em; text-transform:uppercase; color:var(--faint); }

/* The "saved & shared across all tools" note, present but quiet. */
.sharednote{
  display:flex; align-items:center; gap:.55rem; margin-top:1.5rem;
  font-family:var(--mono); font-size:10.5px; letter-spacing:.04em; color:var(--faint);
}
.sharednote::before{ content:''; flex:0 0 auto; width:6px; height:6px; border-radius:50%; background:var(--accent); opacity:.7; }


/* 8 ── MODIFIERS ──────────────────────────────────────────────────────────
   .fields--compact ... (see §1) dense spacing + single-column grid. Use on the
                        settings-drawer "Your details" sub-page.
   .fields--uppercase . opt back into the legacy UPPERCASE MONO field labels
                        (matches _shared.css .calc-label) if a surface needs it.
   Put either class on any wrapper around your fields. */
.fields--uppercase .fld__label{
  font-family:var(--mono); font-size:10px; font-weight:400;
  letter-spacing:.13em; text-transform:uppercase; color:var(--faint);
}

/* Phone: bump input font to 16px so iOS Safari doesn't zoom on focus. */
@media (max-width:600px){
  .fld__input{ font-size:16px; }
}
