/* === InvoiceHelper -- app.css =============================================
   The BUILDER shell. The invoice DOCUMENT styles itself (js/invoice.js) and
   stays light-background on purpose -- a dark PDF wastes toner and reads
   badly on paper.

   DESIGN DIRECTION -- "precision instrument"
   A billing tool earns trust through craft in the controls, not decoration.
   Every control sits in a recessed well with a hairline top highlight, so the
   surface reads as machined rather than flat. Focus is a crisp ring plus a
   brighter top edge -- no blur, no glow. Jost for labels (geometric =
   calibrated), Inter for anything typed.

   CONTENTS
     1. Tokens          6. Sections + fields    10. Dialogs + toast
     2. Reset + base    7. Controls             11. Responsive
     3. Topbar          8. Line items
     4. Buttons         9. Invoice library
     5. Layout
   ========================================================================= */

/* 1. TOKENS ============================================================== */
:root{
  /* surfaces, darkest to lightest */
  --s-base:#0e151b;
  --s-panel:#131c24;
  --s-well:#1a2530;
  --s-raised:#22303c;

  /* strokes */
  --line:#26333f;
  --line-soft:#1e2a35;
  --line-hot:#35485a;
  --line-lift:#2c3a47;

  /* brand */
  --blue:#0085ca;
  --blue-lift:#28a4e8;
  --blue-ghost:rgba(0,133,202,.13);

  /* ink */
  --ink:#e9eef2;
  --ink-mid:#93a1af;
  --ink-low:#606f7d;

  /* status */
  --good:#3ecf8e;
  --warn:#e8a054;
  --bad:#e8505c;

  /* type */
  --f-display:'Jost',system-ui,sans-serif;
  --f-body:'Inter',system-ui,sans-serif;
  --f-mono:ui-monospace,'SF Mono',Menlo,monospace;

  /* rhythm -- a 4px scale keeps vertical spacing honest */
  --sp-1:.25rem; --sp-2:.5rem;  --sp-3:.75rem; --sp-4:1rem;
  --sp-5:1.25rem; --sp-6:1.5rem; --sp-8:2rem;  --sp-10:2.5rem;

  --r-sm:6px; --r:9px; --r-lg:14px;
  --ctl-h:46px;                       /* one control height, everywhere */
  --ease:cubic-bezier(.32,.72,0,1);
  --t-fast:130ms var(--ease);
}

/* 2. RESET + BASE ======================================================== */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--s-base);
  color:var(--ink);
  font:400 15px/1.55 var(--f-body);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
h1,h2,h3{margin:0;font-family:var(--f-display);font-weight:600;letter-spacing:-.01em}
button,input,select,textarea{font:inherit;color:inherit}
:focus-visible{outline:2px solid var(--blue-lift);outline-offset:2px}
::selection{background:var(--blue);color:#fff}

/* Defiant Lab attribution -- deliberately its OWN strip, not part of
   .topbar, so it can never compete with the topbar's already-tight button
   row for space. Sticky (not scrolled-away) so the topbar's sticky offset
   stays correct at every scroll position, not just after scrolling past it. */
.brand-ribbon{
  position:sticky;top:0;z-index:41;
  display:flex;align-items:center;justify-content:center;gap:var(--sp-1);
  height:26px;
  background:var(--s-base);
  border-bottom:1px solid var(--line-soft);
  color:var(--ink-low);font-size:.72rem;text-decoration:none;
  transition:color var(--t-fast),background var(--t-fast);
}
.brand-ribbon:hover{color:var(--blue-lift);background:var(--s-panel)}
.brand-ribbon__icon{width:13px;height:13px;flex:0 0 auto}
.brand-ribbon strong{font-weight:600;color:inherit}

/* 3. TOPBAR ============================================================== */
.topbar{
  position:sticky;top:26px;z-index:40;
  display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);
  padding:var(--sp-3) var(--sp-5);
  background:rgba(14,21,27,.86);
  backdrop-filter:blur(14px) saturate(140%);
  -webkit-backdrop-filter:blur(14px) saturate(140%);
  border-bottom:1px solid var(--line-soft);
}
.topbar__brand{display:flex;align-items:center;gap:var(--sp-2);min-width:0}
.brand__mark svg{display:block;width:30px;height:30px}
.brand__name{
  font-family:var(--f-display);font-weight:600;font-size:1.14rem;
  letter-spacing:-.02em;white-space:nowrap;
}
.brand__accent{color:var(--blue-lift)}
.topbar__actions{display:flex;align-items:center;gap:var(--sp-2)}

/* 4. BUTTONS ============================================================= */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-2);
  height:38px;padding:0 var(--sp-4);
  font-family:var(--f-body);font-size:.83rem;font-weight:550;
  border:1px solid transparent;border-radius:var(--r-sm);
  background:none;cursor:pointer;white-space:nowrap;
  transition:background var(--t-fast),border-color var(--t-fast),color var(--t-fast),transform var(--t-fast);
}
.btn:active{transform:translateY(1px)}

.btn--primary{background:var(--blue);border-color:var(--blue);color:#fff;font-weight:600}
.btn--primary:hover{background:var(--blue-lift);border-color:var(--blue-lift)}
.btn--primary:disabled{background:var(--s-raised);border-color:var(--line);color:var(--ink-low);cursor:not-allowed;transform:none}

.btn--ghost{border-color:var(--line-hot);color:var(--ink-mid)}
.btn--ghost:hover{border-color:var(--blue);color:var(--blue-lift);background:var(--blue-ghost)}

.btn--quiet{color:var(--ink-mid)}
.btn--quiet:hover{background:var(--s-well);color:var(--ink)}

.btn--sm{height:34px;padding:0 var(--sp-3);font-size:.79rem}
.btn--xs{height:28px;padding:0 var(--sp-2);font-size:.74rem}

/* profile badge -- reads as a status chip until hovered */
.btn--badge{
  height:34px;padding:0 var(--sp-3);
  font-family:var(--f-display);font-size:.7rem;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;
  background:var(--s-well);border-color:var(--line);color:var(--ink-mid);
}
.btn--badge:hover{border-color:var(--line-hot);color:var(--ink)}
.btn--badge[data-profile="final"]{
  background:var(--blue-ghost);border-color:rgba(0,133,202,.45);color:var(--blue-lift);
}
.btn--badge[data-profile="final"]::before{
  content:'';width:6px;height:6px;border-radius:50%;background:var(--blue-lift);
  box-shadow:0 0 8px var(--blue-lift);
}

/* 5. LAYOUT ============================================================== */
.layout{display:grid;grid-template-columns:minmax(360px,420px) 1fr;min-height:calc(100vh - 63px)}
.rail{
  padding:var(--sp-6) var(--sp-5) var(--sp-10);
  border-right:1px solid var(--line-soft);
  overflow-y:auto;max-height:calc(100vh - 63px);
  scrollbar-width:thin;scrollbar-color:var(--line-hot) transparent;
}
.rail::-webkit-scrollbar{width:10px}
.rail::-webkit-scrollbar-track{background:transparent}
.rail::-webkit-scrollbar-thumb{background:var(--line-hot);border-radius:99px;border:3px solid var(--s-base)}
.rail::-webkit-scrollbar-thumb:hover{background:var(--ink-low)}

.stage{padding:var(--sp-5);display:flex;min-width:0}
.preview{
  flex:1;min-height:480px;overflow:hidden;
  background:var(--s-panel);
  border:1px solid var(--line-soft);border-radius:var(--r-lg);
  box-shadow:0 24px 60px -20px rgba(0,0,0,.6);
}
#preview-frame{display:block;width:100%;height:100%;min-height:82vh;border:0;background:#fff}

/* 6. SECTIONS + FIELDS =================================================== */
.rail__block{padding-bottom:var(--sp-6);margin-bottom:var(--sp-6);border-bottom:1px solid var(--line-soft)}
.rail__block:last-child{border-bottom:0;margin-bottom:0}

/* The step number is real information: the form is filled in order. */
.rail__title{
  display:flex;align-items:baseline;gap:var(--sp-2);
  margin-bottom:var(--sp-4);
  font-family:var(--f-display);font-size:.7rem;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;color:var(--ink-mid);
}
.rail__title::before{
  content:attr(data-step);
  font-variant-numeric:tabular-nums;color:var(--blue-lift);
}

.field{margin-bottom:var(--sp-4)}
.field:last-child{margin-bottom:0}
.field--row{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3)}
.field--indent{padding-left:var(--sp-4);border-left:2px solid var(--line)}

.label{display:block;margin-bottom:var(--sp-2);font-size:.79rem;font-weight:550;color:var(--ink)}
.label__hint{font-weight:400;color:var(--ink-low);font-size:.75rem}
.note{margin:var(--sp-2) 0 0;font-size:.77rem;color:var(--ink-low)}
.note--warn{color:var(--warn)}

/* 7. CONTROLS ============================================================ */
.input{
  width:100%;height:var(--ctl-h);
  padding:0 var(--sp-3);
  font-size:.92rem;color:var(--ink);
  background:var(--s-well);
  border:1px solid var(--line);
  border-top-color:var(--line-lift);          /* hairline highlight */
  border-radius:var(--r);
  transition:border-color var(--t-fast),background var(--t-fast),box-shadow var(--t-fast);
}
.input::placeholder{color:var(--ink-low)}
.input:hover{border-color:var(--line-hot)}
.input:focus{
  outline:none;
  background:var(--s-raised);
  border-color:var(--blue);
  border-top-color:var(--blue-lift);
  box-shadow:0 0 0 3px var(--blue-ghost);
}
.input--area{height:auto;min-height:84px;padding:var(--sp-3);line-height:1.55;resize:vertical}

/* select: replace the native arrow so it matches the set */
select.input{
  appearance:none;-webkit-appearance:none;
  padding-right:var(--sp-8);cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' stroke='%2393a1af' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right var(--sp-3) center;
}
select.input option{background:var(--s-panel);color:var(--ink)}

/* number: hide spinners -- tiny, ugly, never used here */
input[type="number"].input{appearance:textfield;-moz-appearance:textfield}
input[type="number"].input::-webkit-outer-spin-button,
input[type="number"].input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}

/* FILE: the native control is unstylable browser chrome, so the real input is
   visually hidden and a styled face does the work. */
.filefield{position:relative}
.filefield input[type="file"]{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer}
.filefield__face{
  display:flex;align-items:center;gap:var(--sp-3);
  height:var(--ctl-h);padding:0 var(--sp-3);
  background:var(--s-well);
  border:1px dashed var(--line-hot);border-radius:var(--r);
  color:var(--ink-mid);font-size:.87rem;
  transition:border-color var(--t-fast),background var(--t-fast),color var(--t-fast);
}
.filefield input[type="file"]:hover + .filefield__face,
.filefield input[type="file"]:focus-visible + .filefield__face{
  border-color:var(--blue);background:var(--blue-ghost);color:var(--ink);
}
.filefield__face svg{flex:0 0 auto;width:17px;height:17px}

/* Compact variant -- matches .btn--sm's height so Export/Import read as one
   consistent action row instead of two different control sizes. */
.filefield--inline .filefield__face--sm{
  height:34px;padding:0 var(--sp-3);font-size:.79rem;gap:var(--sp-2);
}
.filefield--inline .filefield__face--sm svg{width:15px;height:15px}
.lib__io{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-2);margin-top:var(--sp-3)}

/* COLOR: swatch + hex field as one unit */
.colorfield{display:grid;grid-template-columns:var(--ctl-h) 1fr;gap:var(--sp-2)}
.colorfield__swatch{
  position:relative;height:var(--ctl-h);
  border:1px solid var(--line);border-radius:var(--r);
  overflow:hidden;cursor:pointer;
  transition:border-color var(--t-fast),transform var(--t-fast);
}
.colorfield__swatch:hover{border-color:var(--line-hot);transform:scale(1.03)}
.colorfield__swatch input[type="color"]{
  position:absolute;inset:-20%;width:140%;height:140%;
  padding:0;border:0;background:none;cursor:pointer;
}
.colorfield .input{font-family:var(--f-mono);font-size:.85rem;letter-spacing:.03em;text-transform:uppercase}

/* logo preview */
.logo-preview{
  display:flex;align-items:center;gap:var(--sp-3);margin-top:var(--sp-2);
  padding:var(--sp-2) var(--sp-3);
  background:var(--s-well);border:1px solid var(--line);border-radius:var(--r);
}
.logo-preview img{
  height:34px;width:auto;max-width:104px;object-fit:contain;
  background:#fff;border-radius:var(--r-sm);padding:3px;
}

/* 8. LINE ITEMS ==========================================================
   A header row labels the columns once instead of repeating placeholders. */
.items__head{
  display:grid;grid-template-columns:1fr 72px 96px;gap:var(--sp-2);
  padding:0 calc(var(--sp-6) + var(--sp-1)) var(--sp-2) var(--sp-3);
  font-family:var(--f-display);font-size:.66rem;font-weight:600;
  letter-spacing:.13em;text-transform:uppercase;color:var(--ink-low);
}
.items__head span:not(:first-child){text-align:right}

.item-row{
  position:relative;display:grid;
  grid-template-columns:1fr 72px 96px;gap:var(--sp-2);
  margin-bottom:var(--sp-2);padding-right:calc(var(--sp-6) + var(--sp-1));
}
.item-row .input{font-size:.88rem}
.item-row .input[data-it-qty],.item-row .input[data-it-rate]{text-align:right;font-variant-numeric:tabular-nums}
.item-row__remove{
  position:absolute;right:0;top:0;
  display:grid;place-items:center;
  width:26px;height:var(--ctl-h);
  border:0;border-radius:var(--r-sm);background:none;
  color:var(--ink-low);cursor:pointer;line-height:1;
  transition:color var(--t-fast),background var(--t-fast);
}
.item-row__remove:hover{background:rgba(232,80,92,.12);color:var(--bad)}

/* 9. INVOICE LIBRARY (premium) =========================================== */
.lib{display:flex;flex-direction:column;gap:var(--sp-2)}
.lib__empty{
  padding:var(--sp-5) var(--sp-4);text-align:center;
  background:var(--s-well);border:1px dashed var(--line);border-radius:var(--r);
  color:var(--ink-low);font-size:.83rem;line-height:1.5;
}
.lib__row{
  display:grid;grid-template-columns:1fr auto;align-items:center;gap:var(--sp-3);
  padding:var(--sp-3);
  background:var(--s-well);border:1px solid var(--line);border-radius:var(--r);
  transition:border-color var(--t-fast),background var(--t-fast);
}
.lib__row:hover{border-color:var(--line-hot);background:var(--s-raised)}
.lib__main{min-width:0}
.lib__who{font-size:.87rem;font-weight:550;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lib__meta{margin-top:2px;font-size:.74rem;color:var(--ink-low);font-variant-numeric:tabular-nums}
.lib__amount{color:var(--blue-lift);font-weight:600}
.lib__acts{display:flex;gap:var(--sp-1)}

/* premium lock -- replaces the feature on the free profile */
.locked{
  padding:var(--sp-5) var(--sp-4);text-align:center;
  background:linear-gradient(var(--blue-ghost),var(--blue-ghost)),var(--s-well);
  border:1px solid rgba(0,133,202,.3);border-radius:var(--r);
}
.locked__title{font-family:var(--f-display);font-size:.92rem;font-weight:600;margin-bottom:var(--sp-1)}
.locked__body{font-size:.81rem;color:var(--ink-mid);line-height:1.5;margin:0 0 var(--sp-3)}

/* 10. DIALOGS + TOAST ====================================================
   <dialog> is a top-layer element: the UA stylesheet sets color:CanvasText
   (black) and it does NOT inherit from body. Must be set explicitly or the
   text renders black-on-dark and vanishes. */
.sheet{
  border:0;padding:0;background:transparent;color:var(--ink);
  max-width:min(460px,calc(100vw - 2rem));
}
.sheet::backdrop{background:rgba(6,10,14,.74);backdrop-filter:blur(4px)}
.sheet__inner{
  display:flex;flex-direction:column;gap:var(--sp-3);
  padding:var(--sp-6);
  background:var(--s-panel);
  border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:0 30px 70px -20px rgba(0,0,0,.7);
}
.sheet__title{font-size:1.16rem}
.sheet__body{margin:0;font-size:.87rem;color:var(--ink-mid);line-height:1.55}
.input--key{height:52px;font-family:var(--f-mono);font-size:.9rem;letter-spacing:.04em;text-align:center}
.sheet__status{margin:0;min-height:1.25em;font-size:.81rem;color:var(--ink-mid)}
.sheet__status[data-state="ok"]{color:var(--good)}
.sheet__status[data-state="err"]{color:var(--warn)}
.sheet__actions{display:flex;justify-content:flex-end;gap:var(--sp-2);margin-top:var(--sp-1)}
.sheet__foot{margin:0;text-align:center;font-size:.79rem;color:var(--ink-low)}
.sheet__foot a{color:var(--blue-lift)}

/* toast -- confirms an action without stealing focus */
/* Floating feedback button. Deliberately NOT in the topbar -- that bar is
   already tight on small screens (see the brand/badge overlap fixed
   earlier), so a 6th element there was a real risk of reintroducing that
   class of bug. A corner FAB is also the more standard pattern for this
   anyway. z-index sits below the mobile preview stage (30) on purpose --
   no reason to float over the invoice itself while it's open. */
.fab{
  position:fixed;right:var(--sp-5);bottom:var(--sp-5);z-index:25;
  display:grid;place-items:center;
  width:52px;height:52px;padding:0;
  background:var(--s-raised);border:1px solid var(--line-hot);border-radius:50%;
  color:var(--ink-mid);cursor:pointer;
  box-shadow:0 12px 30px -8px rgba(0,0,0,.6);
  transition:transform var(--t-fast),border-color var(--t-fast),color var(--t-fast),background var(--t-fast);
}
.fab:hover{transform:translateY(-2px);border-color:var(--blue);color:var(--blue-lift);background:var(--s-well)}
.fab svg{width:22px;height:22px}
@media (max-width:900px){
  .fab{right:var(--sp-4);bottom:var(--sp-4);width:48px;height:48px}
  .fab svg{width:20px;height:20px}
}

.toast{
  position:fixed;left:50%;bottom:var(--sp-6);z-index:60;
  transform:translate(-50%,140%);
  padding:var(--sp-3) var(--sp-5);
  background:var(--s-raised);border:1px solid var(--line-hot);
  border-radius:99px;font-size:.85rem;
  box-shadow:0 16px 40px -12px rgba(0,0,0,.7);
  transition:transform 260ms var(--ease);
}
.toast[data-show="true"]{transform:translate(-50%,0)}

/* 11. RESPONSIVE =========================================================
   <=900px : rail is the page, preview slides over on demand; the extra
             "Preview" toggle appears, so the topbar needs to shed width
             starting here too -- not at a separate, later breakpoint.
   <=430px : brand mark shrinks further for the narrowest phones
   ========================================================================= */
.btn--only-sm{display:none}

@media (max-width:900px){
  .btn--hide-sm{display:none}
  .btn--only-sm{display:inline-flex}

  .layout{grid-template-columns:1fr;min-height:auto}
  .rail{max-height:none;border-right:0;padding:var(--sp-5) var(--sp-4) 6rem}
  .field--row{grid-template-columns:1fr}

  .stage{
    position:fixed;inset:0;top:87px;z-index:30;
    padding:var(--sp-3);background:var(--s-base);
    transform:translateY(101%);visibility:hidden;
    transition:transform 300ms var(--ease),visibility 300ms;
  }
  .stage[data-open="true"]{transform:translateY(0);visibility:visible}
  .preview{min-height:0;display:flex;justify-content:center;align-items:flex-start;overflow:auto}
  /* The invoice is fixed-width Letter and must not reflow, or the preview
     stops matching the PDF. Render true size, scale the frame to fit. */
  #preview-frame{
    flex:0 0 auto;width:816px;height:1056px;min-height:0;
    transform-origin:top center;transform:scale(var(--preview-scale,.42));
  }

  .items__head{display:none}
  .item-row{grid-template-columns:1fr 1fr}
  .item-row .input[data-it-desc]{grid-column:1/-1}

  /* Same range the Preview button appears in: four buttons plus the badge
     now share the bar, so it needs to shed width starting here, not later. */
  .topbar{padding:var(--sp-3) var(--sp-4)}
  .topbar__actions{gap:var(--sp-1)}
  .btn{height:36px;padding:0 var(--sp-3);font-size:.78rem}
  .btn--badge{padding:0 var(--sp-2)}
  .brand__name{display:none}
}

@media (max-width:430px){
  .topbar{padding:var(--sp-3)}
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{transition-duration:.01ms!important;animation-duration:.01ms!important}
  .stage{transition:none}
}
