/* Bhesh — the app shell.
 *
 * The look cards are rendered server-side on cream paper and cannot change: they
 * are PIL images, they get shared publicly, and they are the product. So the shell
 * is built around them rather than over them — a dark room with the cards lit in
 * it, the way a wardrobe looks at night or a garment looks under a shop light.
 * Every card becomes its own lightbox. That is the one place brightness is spent.
 *
 * The accent is the same brass that is already printed on every card, lifted a few
 * steps so it survives on a dark ground. Nothing here introduces a colour the
 * product did not already have.
 */

/* 60 / 30 / 10.
   60  --bg            the ground. Every screen sits on it and nothing else does.
   30  --surface(-2)   the raised things: panels, rows, fields -- and --paper,
                       which is the look card's own cream and the reason this
                       palette exists at all.
   10  --brand + --go  the only two colours that carry meaning.

   THE TEN IS SPLIT, AND THAT IS THE POINT.
   Brass used to be brand and button at once, so a label, a focus ring, a
   progress bar and the one thing we wanted tapped were all the same colour and
   none of them led. Brass now means "this is Bhesh" -- it is the card's own
   colour, printed on every card anyone shares. --go means "do this", and it
   appears on nothing else. A second accent only works while it stays rare.

   Jade against brass rather than a brighter amber: warm and cool read apart at a
   glance, where two warms have to be compared. Measured on this ground -- 6.8:1
   against the page, 6.5:1 under the dark label it carries. Never as text on the
   cream card, where it falls to 2.5:1; the card stays brass. */
:root {
  /* the room */
  --bg:        #0E0F12;
  --surface:   #16181D;
  --surface-2: #1E2128;
  --line:      #262A32;
  --line-firm: #333844;

  /* the light */
  --paper:     #F3F1EC;   /* the cards' own ground — never changes */
  --ink:       #ECEAE4;
  --soft:      #94908A;
  --dim:       #6A675F;
  --brand:     #C89050;   /* the card's brass, lifted for dark */
  --brand-dk:  #965C30;   /* as printed on the card */
  --go:        #0FAE84;   /* actions only */
  --on-go:     #05221A;   /* the label that sits on --go */

  /* --accent is what 32 rules already say. It stays as the brand alias so this
     split is one line of meaning, not a rename across the stylesheet. */
  --accent:    var(--brand);
  --accent-dk: var(--brand-dk);

  --pad: 22px;
  --ease: cubic-bezier(.2, .7, .3, 1);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
}

/* A single display face, used only for headings and numbers. Body stays on the
   system stack: this runs on mid-range Android over Indian mobile data, and a
   second webfont for body text is weight the product cannot justify. */
h1, h2, .count b, .ppct, .phero, .look-n {
  font-family: "Bricolage Grotesque", -apple-system, sans-serif;
  font-variation-settings: "wdth" 96, "opsz" 40;
}

#app { min-height: 100dvh; display: flex; flex-direction: column; }

.screen { display: none; flex: 1; flex-direction: column; padding: var(--pad); }
.screen.on { display: flex; }

/* --- type ---------------------------------------------------------------- */

.brand {
  font-size: 11px; letter-spacing: .24em; text-transform: uppercase;
  color: var(--accent); font-weight: 700;
}
h1 {
  font-size: 31px; line-height: 1.12; margin: 24px 0 10px;
  letter-spacing: -.03em; font-weight: 700;
}
h2 { font-size: 22px; margin: 0 0 4px; letter-spacing: -.02em; font-weight: 700; }
.sub { color: var(--soft); line-height: 1.5; margin: 0 0 26px; font-size: 15px; }
.label {
  font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--soft); font-weight: 700;
}

/* --- controls ------------------------------------------------------------ */

/* Matched by what a field is not, rather than by a type it has to remember to
   declare. `input[type=text]` does not match `<input>` with no type attribute at
   all -- the browser treats that as text but the selector does not -- which left
   the Ask screen's refine box completely unstyled: a white system box in a dark
   app, the one thing on screen that looked like a form rather than a product. */
input:not([type=file]):not([type=checkbox]):not([type=radio]):not([type=submit]) {
  width: 100%; padding: 15px 16px; font-size: 17px;
  border: 1.5px solid var(--line-firm); border-radius: 12px;
  background: var(--surface); color: var(--ink); font-family: inherit;
  transition: border-color .18s var(--ease), background .18s var(--ease);
}
input::placeholder { color: var(--dim); }
input:focus {
  outline: none; border-color: var(--accent); background: var(--surface-2);
}

.phone-row { display: flex; gap: 9px; align-items: stretch; }
.cc {
  display: flex; align-items: center; padding: 0 15px; font-size: 17px;
  border: 1.5px solid var(--line-firm); border-radius: 12px;
  background: var(--surface); color: var(--soft); flex: none;
}

/* The filled button is the only thing on a screen wearing --go, which is what
   makes it the thing your eye lands on. Ghost buttons stay neutral and pick up
   brass on hover: a second filled button beside this one would put two answers
   where the screen is asking for one. */
.btn {
  width: 100%; padding: 16px; font-size: 16px; font-weight: 650;
  border: none; border-radius: 12px; background: var(--go); color: var(--on-go);
  font-family: inherit; cursor: pointer; margin-top: 16px;
  transition: transform .12s var(--ease), filter .18s var(--ease);
}
.btn:hover:not(:disabled) { filter: brightness(1.08); }
.btn:active:not(:disabled) { transform: scale(.985); }
.btn:disabled { opacity: .3; background: var(--surface-2); color: var(--soft); }
.btn.ghost {
  background: none; color: var(--ink); border: 1.5px solid var(--line-firm);
}
.btn.ghost:hover { border-color: var(--accent); color: var(--accent); }
.btn.small { width: auto; padding: 11px 18px; font-size: 14px; margin: 0; }

.linkish {
  background: none; border: none; color: var(--accent); font-family: inherit;
  font-size: 14px; padding: 12px 0; cursor: pointer; text-align: left;
}

.err { color: #E27C6B; font-size: 14px; min-height: 20px; margin-top: 10px; }
.note {
  font-size: 13px; color: var(--soft); background: var(--surface);
  border: 1px solid var(--line); border-radius: 10px; padding: 11px 13px;
  margin-top: 16px; line-height: 1.45;
}

/* --- otp ----------------------------------------------------------------- */

.otp {
  letter-spacing: .55em; font-size: 25px; text-align: center;
  padding-left: .55em;
}

/* --- upload -------------------------------------------------------------- */

.drop {
  border: 1.5px dashed var(--line-firm); border-radius: 16px; padding: 34px 20px;
  text-align: center; background: var(--surface); cursor: pointer;
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
.drop:hover { border-color: var(--accent); background: var(--surface-2); }
.drop .big { font-size: 34px; margin-bottom: 12px; }
.drop .t { font-weight: 650; margin-bottom: 5px; }
.drop .s { color: var(--soft); font-size: 14px; line-height: 1.45; }

.thumbs {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px; margin-top: 16px;
}
.thumbs img { width: 100%; aspect-ratio: 3/4; object-fit: cover; border-radius: 7px; }

.tips { margin: 22px 0 0; padding: 0; list-style: none; }
/* Block, not flex: as a flex row the bold lead-in became its own column and
   "Filter nahi" wrapped inside it, knocking the dash and the rest out of line. */
.tips li {
  color: var(--soft); font-size: 14px;
  padding: 7px 0; line-height: 1.45;
}
.tips li b { color: var(--ink); font-weight: 650; }

/* --- progress ------------------------------------------------------------ */

.steps { margin-top: 30px; }
.step {
  display: flex; align-items: center; gap: 13px; padding: 13px 0;
  border-bottom: 1px solid var(--line); color: var(--soft);
}
.step:last-child { border-bottom: none; }
.step.on, .step.done { color: var(--ink); }
.dot {
  width: 9px; height: 9px; border-radius: 50%; background: var(--line); flex: none;
}
.step.on .dot { background: var(--accent); animation: pulse 1.1s infinite; }
.step.done .dot { background: var(--ink); }
@keyframes pulse { 50% { opacity: .3; } }
.step .n { margin-left: auto; font-size: 13px; font-variant-numeric: tabular-nums; }

.bar { height: 3px; background: var(--surface-2); border-radius: 2px; overflow: hidden; }
.bar > i { display: block; height: 100%; background: var(--accent); width: 0; transition: width .3s; }

/* --- wardrobe ------------------------------------------------------------ */

.counts { display: flex; gap: 7px; margin: 18px 0 22px; }
.count {
  flex: 1; background: var(--surface); border: 1px solid var(--line);
  border-radius: 11px; padding: 13px 8px; text-align: center;
}
.count b { font-size: 25px; letter-spacing: -.03em; }
.count b { display: block; font-size: 23px; letter-spacing: -.02em; }
.count span { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--soft); }

.grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px; }
.item {
  background: var(--surface); border: 1px solid var(--line); border-radius: 11px;
  padding: 13px; display: flex; align-items: center; gap: 11px;
  transition: border-color .18s var(--ease);
}
.item:hover { border-color: var(--line-firm); }
.swatch { width: 26px; height: 26px; border-radius: 6px; border: 1px solid var(--line); flex: none; }
.item .n { font-size: 13.5px; line-height: 1.3; text-transform: capitalize; }
.item .u { font-size: 11px; color: var(--soft); }
/* Provenance, deliberately quiet: it matters when a garment looks wrong and is
   noise the rest of the time, so it sits below the name in the dimmest ink on
   the screen and never competes with it. */
.item .src {
  font-size: 10.5px; color: var(--dim); margin-top: 3px;
  letter-spacing: .02em; font-variant-numeric: tabular-nums;
}

/* "Not right?" — on every garment, not only the ones the model doubted.
   Quiet until wanted: it is the answer to a question the person is already
   asking when they look at a wrong name, and clutter on the forty that are
   right. It sits on the row rather than inside the name so a long label cannot
   push it out of reach. */
.item { position: relative; }
.item .fix {
  align-self: center; flex: none; margin-left: auto;
  background: none; border: none; font-family: inherit; cursor: pointer;
  font-size: 11px; color: var(--dim); padding: 6px 2px 6px 10px;
  white-space: nowrap; transition: color .16s var(--ease);
}
.item .fix:hover { color: var(--accent); }

.fixbox {
  grid-column: 1 / -1;
  background: var(--surface-2); border: 1px solid var(--line-firm);
  border-radius: 11px; padding: 14px; margin: -4px 0 4px;
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
}
.fixbox label { font-size: 13px; color: var(--soft); }

/* The type picker, which is a menu rather than a <select>.
   A native dropdown is one level deep and cannot branch, and the denim cuts
   need a branch: Jeans carries an arrow, and the arrow opens the cuts beside
   it. Everything below exists to make that branch behave the same under a
   mouse and under a thumb. */
.pick { position: relative; flex: 1 1 170px; min-width: 0; }
.pick-btn {
  width: 100%; display: flex; align-items: center; gap: 8px;
  padding: 9px 10px; font-size: 14px; font-family: inherit; text-align: left;
  color: var(--ink); background: var(--surface);
  border: 1.5px solid var(--line-firm); border-radius: 9px; cursor: pointer;
}
.pick-btn .pick-now { flex: 1; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.pick-btn i { font-style: normal; color: var(--soft); font-size: 11px; }
.pick-btn:focus-visible { outline: none; border-color: var(--accent); }

.pick-menu {
  position: absolute; z-index: 40; top: calc(100% + 5px); left: 0;
  min-width: 100%; padding: 5px; border-radius: 10px;
  background: var(--surface-2); border: 1px solid var(--line-firm);
  box-shadow: 0 16px 38px rgba(0, 0, 0, .55);
  max-height: 300px; overflow-y: auto;
}
.mi {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 10px; border: 0; border-radius: 7px; cursor: pointer;
  font-family: inherit; font-size: 14px; text-align: left;
  color: var(--ink); background: none; text-transform: capitalize;
}
.mi i { margin-left: auto; font-style: normal; color: var(--soft); font-size: 14px; }
.mi:hover, .mi:focus-visible { background: var(--surface); outline: none; }

/* A branch and the panel it opens.
   The panel is `position: fixed`, and that is the fix rather than a preference.
   It was absolutely positioned inside .pick-menu, which scrolls -- and an
   overflow ancestor clips an absolutely positioned descendant. Hovering Jeans
   was opening the branch the whole time; the browser was drawing it outside the
   scrolling box and clipping every pixel of it away. A fixed element's
   containing block is the viewport, so no overflow ancestor can clip it, and
   the menu keeps its scroll for the twenty-odd tops.
   Its coordinates come from JS, since fixed means the row's position no longer
   places it. It stays a DOM child of the row so travelling from Jeans across to
   Bootcut never leaves the element that keeps it open. */
.mi-sub { position: relative; }
/* Styled on its own selector, not as a descendant of the row. It is moved onto
   <body> when it opens, and a descendant selector stops matching the moment it
   moves -- which took its position, its width and its background with it and
   left a full-width block across the foot of the page. */
.sub {
  display: none; position: fixed; z-index: 60;
  width: max-content; min-width: 156px; padding: 5px; border-radius: 10px;
  background: var(--surface-2); border: 1px solid var(--line-firm);
  box-shadow: 0 16px 38px rgba(0, 0, 0, .55);
}
.sub .mi { text-transform: none; }
/* The panel is moved onto <body>, so it is no longer a descendant of the row
   and cannot be shown by a selector that walks down from it. It carries its own
   class instead. */
.sub.open { display: block; }
.mi-sub.open > .has-sub { background: var(--surface); }
.fixbox select {
  flex: 1 1 130px; min-width: 0;
  padding: 9px 10px; font-size: 14px; font-family: inherit;
  color: var(--ink); background: var(--surface);
  border: 1.5px solid var(--line-firm); border-radius: 9px;
  text-transform: capitalize;
}
.fixbox select:focus { outline: none; border-color: var(--accent); }
.fixrow { display: flex; align-items: center; gap: 8px; width: 100%; margin-top: 2px; }
.fixerr { font-size: 12px; color: #D3705E; }

/* The photo roll: what the person put in, under what the app made of it.
   Two columns like the garment grid above it, so the screen reads as one list
   that changes from output to input rather than as a second screen bolted on.
   The photographs are somebody's own mirror selfies, so they are shown plainly
   -- no halo, no lift. That treatment belongs to the cards alone. */
.roll { display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px; }
.shot {
  margin: 0; background: var(--surface); position: relative;
  border: 1px solid var(--line); border-radius: 11px; overflow: hidden;
}
/* The number a look card means when it says FROM PHOTO 6.
   On the picture rather than beside it, because it has to survive being
   scrolled past at speed while someone hunts for one specific shot. Its own
   dark plate under it: these are mirror selfies, and a number set straight onto
   an unknown photograph is legible over half of them at best. */
.shot .no {
  position: absolute; top: 7px; left: 7px;
  min-width: 21px; height: 21px; padding: 0 6px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(14, 15, 18, .82); color: var(--paper);
  border-radius: 6px; font-size: 11.5px; font-weight: 700;
  font-variant-numeric: tabular-nums; letter-spacing: .02em;
  backdrop-filter: blur(3px);
}
.shot.empty .no { background: rgba(14, 15, 18, .55); color: var(--dim); }
.shot img {
  display: block; width: 100%; aspect-ratio: 3 / 4; object-fit: cover;
  background: var(--surface-2);
}
.shot figcaption {
  padding: 9px 11px 11px; font-size: 11.5px; line-height: 1.35;
  color: var(--soft); text-transform: capitalize;
}
/* The count is the thing being compared photo to photo, so it carries the
   weight and the brass; the names beside it are the evidence for it. */
.shot figcaption b {
  color: var(--accent); font-size: 13px; margin-right: 5px;
  font-variant-numeric: tabular-nums;
}
/* A photo nothing was read from is the one worth replacing, so it says so
   rather than sitting in the grid looking like the others. */
.shot.empty { border-style: dashed; }
.shot.empty img { opacity: .45; }
.shot.empty figcaption { text-transform: none; color: var(--dim); }
.shot.empty figcaption b { color: var(--dim); }

.q {
  background: var(--surface); border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 11px; padding: 15px; margin-bottom: 10px;
}
.q .t { font-weight: 650; margin-bottom: 11px; line-height: 1.35; }
/* Only the garment name is a name; capitalising the whole sentence turned
   "white checked jacket ka rang kaunsa hai?" into title case and it read wrong. */
.q .t em { font-style: normal; text-transform: capitalize; }
.opts { display: flex; flex-wrap: wrap; gap: 7px; }
.opt {
  padding: 9px 14px; border: 1.5px solid var(--line-firm); border-radius: 999px;
  background: var(--surface-2); font-size: 14px; font-family: inherit;
  cursor: pointer; text-transform: capitalize; color: var(--ink);
  transition: border-color .15s var(--ease), color .15s var(--ease);
}
.opt:hover { border-color: var(--accent); color: var(--accent); }

/* --- cards --------------------------------------------------------------- */

.deck { display: flex; overflow-x: auto; gap: 13px; scroll-snap-type: x mandatory;
        margin: 0 calc(-1 * var(--pad)); padding: 0 var(--pad) 6px; }
.deck::-webkit-scrollbar { display: none; }
.look { flex: 0 0 84%; scroll-snap-align: center; }
/* THE SIGNATURE.
   Cards arrive on cream and cannot be restyled, so the shell treats them as lit
   objects instead of fighting them: a warm halo, a hairline of the card's own
   brass, and a lift on hover. On a dark ground a cream card already glows; this
   just admits it. Nothing else on the page is allowed this treatment. */
.look img {
  width: 100%; border-radius: 14px; display: block;
  border: 1px solid rgba(200, 144, 80, .22);
  background: var(--paper);
  box-shadow:
    0 0 0 1px rgba(0,0,0,.4),
    0 18px 40px -12px rgba(0,0,0,.7),
    0 0 60px -18px rgba(200, 144, 80, .28);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}
.look:hover img {
  transform: translateY(-4px);
  box-shadow:
    0 0 0 1px rgba(0,0,0,.4),
    0 26px 54px -14px rgba(0,0,0,.75),
    0 0 78px -14px rgba(200, 144, 80, .4);
}
#today-img {
  box-shadow:
    0 0 0 1px rgba(0,0,0,.4),
    0 18px 40px -12px rgba(0,0,0,.7),
    0 0 60px -18px rgba(200, 144, 80, .28);
  border-color: rgba(200, 144, 80, .22) !important;
}
.look .cap { font-size: 13px; color: var(--soft); margin-top: 9px; line-height: 1.4; }

.today {
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  padding: 22px; margin-bottom: 18px;
}
.today .line { font-size: 16.5px; line-height: 1.5; }
/* The piece list is uppercase at 11px with .16em of letter-spacing, and on a
   four-garment outfit it wraps to two or three lines. .label sets no
   line-height at all, so those lines inherited the body's and closed up against
   each other -- wide tracking needs the opposite treatment, more leading, not
   less, or the block reads as one grey mass.
   The rule is scoped to this card, so the same class stays compact everywhere
   it is a single line and does not need the room. */
.today .label { line-height: 1.95; }
/* A hairline instead of guessing at a gap: the sentence and the list are two
   different things -- one is the suggestion, the other is its ingredients --
   and separating them by space alone needed so much of it that the card grew a
   hole in the middle. */
.today .label {
  margin-top: 15px; padding-top: 14px; border-top: 1px solid var(--line);
}

.tabs {
  display: flex; border-top: 1px solid var(--line);
  background: rgba(14, 15, 18, .92); backdrop-filter: blur(12px);
  position: sticky; bottom: 0; padding-bottom: env(safe-area-inset-bottom);
  z-index: 5;
}
.tabs button {
  flex: 1; padding: 14px 4px; background: none; border: none; font-family: inherit;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--soft); font-weight: 700; cursor: pointer;
}
.tabs button.on { color: var(--ink); box-shadow: inset 0 2px 0 var(--accent); }
.tabs button:hover { color: var(--ink); }

.spacer { flex: 1; }
.hide { display: none !important; }

/* --- style meter --------------------------------------------------------- */

.phero { color: var(--accent); text-transform: capitalize; }

.pbar { margin-bottom: 20px; }
.ptop { display: flex; justify-content: baseline; align-items: baseline; gap: 8px; }
.pname {
  font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
  font-weight: 700; flex: 1;
}
.ppct { font-size: 19px; font-weight: 650; font-variant-numeric: tabular-nums; }
.ptrack {
  height: 8px; background: var(--surface-2); border-radius: 4px;
  overflow: hidden; margin: 8px 0 6px;
}
/* The one orchestrated moment: the bars grow from nothing when the meter is
   first seen. It is the screen people screenshot, so it earns the motion. */
.ptrack > i {
  display: block; height: 100%; background: var(--soft);
  width: 0; transition: width .9s var(--ease);
}
.pbar:first-child .ptrack > i { background: var(--accent); }
.pbar:first-child .ptrack > i { background: var(--accent); }
.pev { font-size: 13px; color: var(--soft); text-transform: capitalize; line-height: 1.4; }

/* --- upload feedback ------------------------------------------------------ */

.picknote {
  font-size: 14px; line-height: 1.45; margin-top: 16px; min-height: 20px;
  color: var(--soft);
}
.picknote.warn { color: #a8352a; }
.picknote.ok { color: var(--accent); }

/* --- camera --------------------------------------------------------------- */

.or {
  text-align: center; color: var(--soft); font-size: 13px; margin: 14px 0 10px;
  letter-spacing: .08em; text-transform: uppercase;
}

.screen.cam { padding: 0; background: #0d0d0e; }
.camwrap { position: relative; flex: 1; overflow: hidden; }
#cam { width: 100%; height: 100%; object-fit: cover; display: block; }

.camguide {
  position: absolute; inset: 0; width: 100%; height: 100%;
  color: #fff; pointer-events: none;
}
/* A pill, not bare text. These labels land on whatever the room happens to be --
   a dark shirt swallowed the feet label completely on the first try, and that is
   the one label this screen exists for. */
.camlabel {
  position: absolute; left: 0; right: 0; text-align: center;
  font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  pointer-events: none; font-weight: 700;
}
.camlabel span {
  display: inline-block; padding: 4px 10px; border-radius: 999px;
  background: rgba(13, 13, 14, .62); color: rgba(255,255,255,.95);
}
.camlabel.top { top: 2%; }
.camlabel.feet { top: 79%; }
.camlabel.feet span { background: var(--accent); color: #fff; }

.camtip {
  position: absolute; left: 16px; right: 16px; bottom: 14px;
  color: #fff; font-size: 14px; line-height: 1.45; text-align: center;
  text-shadow: 0 1px 4px rgba(0,0,0,.7);
}

.camrow {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px calc(14px + env(safe-area-inset-bottom));
  background: #0d0d0e;
}
.camrow .linkish { color: #cfcbc4; font-size: 13px; }

.shutter {
  width: 66px; height: 66px; border-radius: 50%;
  background: #fff; border: 4px solid rgba(255,255,255,.35);
  cursor: pointer; flex: none;
}
.shutter:active { transform: scale(.94); }
.shutter:disabled { opacity: .4; }

.camerr { color: #e2897c; font-size: 14px; padding: 0 18px; text-align: center; }
#cam-thumbs { padding: 0 14px 12px; }

/* --- occasion chips + share ----------------------------------------------- */

.chips {
  display: flex; gap: 7px; overflow-x: auto; padding-bottom: 12px;
  margin: 0 calc(-1 * var(--pad)); padding-left: var(--pad); padding-right: var(--pad);
}
.chips::-webkit-scrollbar { display: none; }
.chip {
  flex: none; padding: 8px 14px; border-radius: 999px; font-size: 13.5px;
  border: 1.5px solid var(--line-firm); background: var(--surface);
  color: var(--soft); font-family: inherit; cursor: pointer; white-space: nowrap;
  transition: all .16s var(--ease);
}
.chip:hover { color: var(--ink); border-color: var(--soft); }
.chip.on {
  background: var(--accent); color: #14161A; border-color: var(--accent);
  font-weight: 650;
}
.chip.locked { color: var(--soft); }

.look .row { display: flex; align-items: center; gap: 10px; margin-top: 9px; }
.look .cap { flex: 1; margin-top: 0; }
.share {
  flex: none; padding: 8px 14px; border-radius: 999px; font-size: 13px;
  border: 1.5px solid var(--accent); background: none; color: var(--accent);
  font-family: inherit; font-weight: 650; cursor: pointer;
  transition: background .16s var(--ease), color .16s var(--ease);
}
.share:hover { background: var(--accent); color: #14161A; }
.share.done { border-color: var(--line); color: var(--soft); }

.unlocknote {
  background: var(--surface); border: 1px solid var(--line);
  border-left: 3px solid var(--accent); border-radius: 11px;
  padding: 13px 15px; font-size: 14px; line-height: 1.45; margin-bottom: 14px;
}

/* --- wardrobe gaps -------------------------------------------------------- */

.gap {
  display: flex; align-items: center; gap: 13px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 11px;
  padding: 13px; margin-bottom: 9px;
  transition: border-color .18s var(--ease);
}
.gap:hover { border-color: var(--line-firm); }
.gap .sw { width: 34px; height: 34px; border-radius: 8px; border: 1px solid var(--line); flex: none; }
.gap .txt { flex: 1; min-width: 0; }
.gap .n { font-size: 14.5px; text-transform: capitalize; line-height: 1.25; }
.gap .g { font-size: 13px; color: var(--accent); font-weight: 650; margin-top: 2px; }
/* Outlined, not filled. Four solid dark pills stacked made the panel read as an
   ad block, which is the opposite of what this feature is -- the number beside
   each garment is the argument, and the button should not shout over it. Same
   treatment as the share button, so an outbound link looks like every other
   secondary action in the app. */
.gap a {
  flex: none; padding: 8px 15px; border-radius: 999px; font-size: 13px;
  border: 1.5px solid var(--accent); color: var(--accent);
  background: none; text-decoration: none; font-weight: 650; white-space: nowrap;
}
.gap .g b { color: var(--accent); font-weight: 700; }

/* The tab bar sits over the end of this panel, so the last line needs room. */
#gaps { padding-bottom: 18px; }


/* --- motion --------------------------------------------------------------- */

/* Content rises in on arrival, in the order it is read. 55ms apart is enough to
   feel sequenced and not enough to feel slow. */
@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
.screen.on > * { animation: rise .42s var(--ease) both; }
.screen.on > *:nth-child(1) { animation-delay: .02s; }
.screen.on > *:nth-child(2) { animation-delay: .07s; }
.screen.on > *:nth-child(3) { animation-delay: .12s; }
.screen.on > *:nth-child(4) { animation-delay: .17s; }
.screen.on > *:nth-child(5) { animation-delay: .22s; }

/* Cards float up one after another as each reaches the screen, like prints being
   laid out on a table.

   WHY AN OBSERVER AND NOT A DELAY ON LOAD
   This used to be `animation: rise` with nth-child delays, every card firing
   when the deck rendered. Twelve cards arrive at once and nine of them are below
   the fold, so their animation ran and finished while they were still off
   screen -- by the time you scrolled down they had already landed and there was
   nothing left to see. The stagger was real and almost entirely invisible.
   Each card now waits for its own turn on screen instead of for the clock.

   The hidden state is scoped to .js-anim, which app.js sets. If that script
   never runs the deck renders plainly visible, because a scripting failure must
   not leave someone staring at an empty page where their outfits should be. */
.js-anim .look {
  opacity: 0;
  transform: translateY(18px) scale(.985);
  transition: opacity .55s var(--ease), transform .55s var(--ease);
  transition-delay: var(--in-delay, 0s);
}
.js-anim .look.in { opacity: 1; transform: none; }

.gap, .item, .q { animation: rise .4s var(--ease) both; }
.gap:nth-child(2), .item:nth-child(2) { animation-delay: .05s; }
.gap:nth-child(3), .item:nth-child(3) { animation-delay: .10s; }
.gap:nth-child(4), .item:nth-child(4) { animation-delay: .15s; }

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

/* --- desktop -------------------------------------------------------------- */

/* Below 900px this is a phone and the bottom tab bar is correct. Above it, a
   460px column centred in a 1400px window is a phone screenshot pretending to be
   a website, so the nav goes to a rail and the deck becomes a grid. */
@media (min-width: 900px) {
  :root { --pad: 40px; }

  .screen { max-width: 1240px; margin: 0 auto; width: 100%; }

  #s-main {
    display: grid;
    grid-template-columns: 210px minmax(0, 1fr);
    grid-template-areas: "nav body";
    gap: 0 48px;
    align-items: start;
    padding-top: 44px;
  }
  #s-main > .spacer { display: none; }

  .tabs {
    grid-area: nav; position: sticky; top: 44px;
    flex-direction: column; align-items: stretch;
    border-top: none; border-right: none;
    background: none; backdrop-filter: none; padding: 0 20px 0 0;
    gap: 2px;
  }
  .tabs button {
    text-align: left; padding: 12px 14px; border-radius: 9px; font-size: 12px;
  }
  .tabs button.on {
    box-shadow: none; background: var(--surface); color: var(--accent);
  }
  .tabs::before {
    content: "Bhesh"; display: block;
    font-size: 11px; letter-spacing: .24em; text-transform: uppercase;
    color: var(--accent); font-weight: 700; padding: 0 14px 22px;
  }

  #tab-today, #tab-looks, #tab-style, #tab-wardrobe { grid-area: body; }

  /* One rule down the page rather than a stub beside four links — it belongs to
     the layout, not to the nav's own height. */
  #s-main::before {
    content: ""; grid-area: nav;
    justify-self: end; align-self: stretch;
    width: 1px; background: var(--line); margin-right: -24px; min-height: 70vh;
  }

  /* The deck stops being a swipe and becomes a wall of prints. */
  .deck {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px;
    overflow: visible; margin: 0; padding: 0;
  }
  .look { flex: none; }

  /* Today is a caption and a card, not a three-row grid. Spanning the image
     across rows stretched the left column and opened dead space between every
     line of it. The text column stacks tight at the top; the card sits beside it. */
  #tab-today {
    display: grid; grid-template-columns: minmax(0, 1fr) 420px;
    gap: 0 48px; align-items: start; align-content: start;
  }
  #tab-today.hide { display: none; }
  #tab-today > .brand, #tab-today > .today, #tab-today > #wore { grid-column: 1; }
  #tab-today > #wore { margin-top: 4px; max-width: 280px; }
  #today-img { grid-column: 2; grid-row: 1 / span 4; margin: 0; }

  .grid { grid-template-columns: repeat(3, 1fr); }
  .counts { max-width: 640px; }
  h1 { font-size: 42px; }
}

/* On a phone the screens are the whole product; give the last item room to clear
   the tab bar. */
@media (max-width: 899px) {
  #tab-today, #tab-looks, #tab-style, #tab-wardrobe { padding-bottom: 8px; }
}

/* --- plans ---------------------------------------------------------------- */

/* One quiet line, and only once the allowance is nearly gone. A counter shown
   from photo one is a nag about a limit weeks away. */
.planline {
  font-size: 13px; color: var(--soft); margin-top: 14px;
  display: flex; align-items: center; gap: 8px;
}
.planline b { color: var(--ink); font-weight: 650; }
.planline {
  flex-wrap: wrap; line-height: 1.5;
}
.planline button {
  background: none; border: none; color: var(--accent); font-family: inherit;
  font-size: 13px; font-weight: 650; cursor: pointer; padding: 0;
}
/* Only once the cap is actually reached. Before that this line is a counter and
   a quiet link; a filled button sitting beside "8 of 12 left" is a shop pushing
   at somebody who has not asked for anything. */
.planline button.hot {
  background: var(--go); color: var(--on-go);
  padding: 9px 15px; border-radius: 999px; white-space: nowrap;
  transition: filter .18s var(--ease);
}
.planline button.hot:hover { filter: brightness(1.08); }

/* The price anchor on the Premium card. Set in the brand, not in --go: it is a
   fact about the price, and --go belongs to the button underneath it. */
.anchor {
  font-size: 13px; color: var(--accent); font-weight: 650;
  margin: -2px 0 10px; letter-spacing: -.005em;
}

.plan {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 14px; padding: 20px; margin-bottom: 12px;
}
.plan.up { border-color: var(--accent); background: var(--surface-2); }
.plan .top { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; }
.plan .nm { font-size: 18px; font-weight: 700; letter-spacing: -.01em; }
.plan .pr { font-size: 15px; color: var(--accent); font-weight: 650; }
.plan .pr small { color: var(--soft); font-weight: 400; }
.plan .pitch { font-size: 14px; color: var(--soft); margin: 2px 0 14px; }
.plan ul { list-style: none; margin: 0; padding: 0; }
.plan li {
  font-size: 14px; line-height: 1.45; color: var(--ink);
  padding: 6px 0 6px 20px; position: relative;
}
.plan li::before {
  content: ""; position: absolute; left: 2px; top: 13px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--accent);
}
.plan .soon {
  margin-top: 14px; font-size: 13px; color: var(--soft);
  border-top: 1px solid var(--line); padding-top: 12px; line-height: 1.45;
}


/* ── Ask ─────────────────────────────────────────────────────────────────
   The answer is set on the card's own paper, not on the app's dark surface.
   Everywhere else in this app, paper means "this is about your clothes" --
   the look cards, the shared image. An answer about your wardrobe belongs on
   the same ground, and it reads as a note someone wrote rather than a chat
   bubble the machine emitted. */
/* The selected chip is styled by .chip.on with every other chip in the app. The
   one-off rule that used to sit here coloured the selected one only, which is
   why the rest looked like system buttons and nobody noticed the class was
   missing -- the screen looked half-designed rather than broken. */
#ask-refine { margin-bottom: 12px; }

.answer {
  background: var(--paper);
  color: #24211C;
  border-radius: 14px;
  padding: 20px 20px 16px;
  margin-top: 18px;
  line-height: 1.62;
  font-size: 15.5px;
  box-shadow: 0 1px 0 rgba(200,144,80,.30), 0 18px 44px -22px rgba(0,0,0,.85);
  animation: rise .42s cubic-bezier(.2,.7,.3,1) both;
}
.answer .occ {
  font-size: 11px; letter-spacing: .13em; text-transform: uppercase;
  color: #8A7C63; display: block; margin-bottom: 10px;
}
.answer p { margin: 0 0 10px; }
.answer p:last-child { margin-bottom: 0; }

.thinking { color: var(--soft); font-size: 14px; margin-top: 18px; }
.thinking::after { content: "…"; animation: dots 1.4s steps(4,end) infinite; }
@keyframes dots { 0% { content: ""; } 25% { content: "."; } 50% { content: ".."; } 75% { content: "…"; } }
