/* ===========================================================================
   THE VAULT — the room's own rules.
   ===========================================================================
   Moved out of app.css (rebuild, 15 Oct). Loaded right after it. The medicine
   cabinet borrows the vault's card, strip and gate classes on purpose, so those
   live here and are not the cabinet's to restate.

   STAYS IN app.css because other pages use it: .vault-head (fourteen page
   headers), .vault-cats / .vault-cat / .vault-cat-n (the Feed's filter chips),
   .vault-row2 (two-column form rows) and the press-feedback rules that name
   .vault-card.

   .vault-cards and .vault-grid used to be declared here with their own track
   widths and then overridden by the shared tile-grid rule (--tile-min,
   --tile-gap, --tile-span) far below; the rules below are the result.
   =========================================================================== */

/* THE LANDING: large cards, one per kind.
   A card face carries a count and the next date and NOTHING ELSE — the
   contents are one click further in, on their own page. The whole complaint
   about the old screen was that it was a flat list; a wall of tabs over the
   same list would have been the same screen with more chrome. */
.vault-cards{ display:grid; grid-template-columns:repeat(auto-fill, minmax(min(100%, var(--tile-min)), 1fr));
  gap:var(--tile-gap); align-items:start; max-width:var(--tile-span); margin-bottom:var(--space-2); }
.vault-card{ position:relative; overflow:hidden; padding:var(--space-5); border-radius:var(--radius-card);
  cursor:pointer; min-height:132px; display:flex; flex-direction:column;
  justify-content:space-between; border:1px solid var(--glass-border);
  background:var(--glass-bg);
  transition:transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out); }
.vault-card:hover{ transform:translateY(-2px); }
:root:not([data-mode="light"]) .vault-card{
  background-image:linear-gradient(140deg, color-mix(in srgb, var(--vc-glow, transparent) 40%, transparent) 0%, transparent 58%); }
:root:not([data-mode="light"]) .vault-card:hover{
  box-shadow:0 0 0 1px color-mix(in srgb, var(--vc, var(--accent)) 34%, transparent),
             0 14px 40px -14px var(--vc-glow, transparent); }
:root[data-mode="light"] .vault-card:hover{ box-shadow:var(--elev-raised); }
.vault-card-icon{ width:24px; height:24px; color:var(--vc, var(--accent)); margin-bottom:auto; }
.vault-card-name{ font-size:var(--type-lead); font-weight:650; margin-top:var(--space-4); }
.vault-card-n{ font-size:var(--type-body); color:var(--text-dim); margin-top:var(--space-1); }
.vault-card-due{ font-size:var(--type-body); font-weight:600; color:var(--vc-text, var(--text-dim)); margin-top:var(--space-2); }
.vault-card-locked{ position:absolute; top:16px; right:16px; width:15px; height:15px; color:var(--text-dim); }

.vault-lockbox{ margin-top:var(--space-8); padding-top:var(--space-5); border-top:1px solid var(--glass-border); }
.vault-back{ font-size:var(--type-body); font-weight:600; color:var(--text-dim); cursor:pointer; margin-bottom:var(--space-2); }
.vault-back:hover{ color:var(--text); }
.vault-lockstate{ font-size:var(--type-body); color:var(--text-dim); }

/* The gate. Not an overlay with the page behind it — the page is not drawn
   at all while this is up. */
.vault-gate{ display:flex; align-items:center; justify-content:center; padding:var(--space-16) var(--space-5); }
.vault-gate-inner{ max-width:380px; text-align:center; }
.vault-gate-icon{ width:44px; height:44px; color:var(--text-dim); margin-bottom:var(--space-4); }
.vault-gate-title{ font-family:var(--font-display); font-size:var(--type-page); font-weight:600; margin-bottom:var(--space-2); }

/* A hidden item still occupies its row, because a vault that silently omits
   things is indistinguishable from one that lost them. */
.vault-hidden-val{ font-family:var(--font-mono); letter-spacing:.12em;
  color:var(--text-faint); }

.vault-renewals{ margin-bottom:var(--space-6); }
.vault-renew{ display:flex; align-items:baseline; justify-content:space-between; gap:var(--space-4);
  padding:var(--space-3) 0 var(--space-3) var(--space-4); position:relative; cursor:pointer; }
.vault-renew + .vault-renew{ border-top:1px solid var(--glass-border); }
/* Same margin rule as the Home cards: the mark is always there, only its
   brightness changes. See the note by .ht-card. */
.vault-renew::before{ content:''; position:absolute; left:0; top:14px; bottom:14px; width:2px;
  border-radius:var(--radius-tight); z-index:0; background:color-mix(in srgb, var(--text) 13%, transparent); }
.vault-renew.hot::before{ background:var(--accent); }
:root:not([data-mode="light"]) .vault-renew.hot::before{ box-shadow:0 0 12px 1px var(--accent-glow); }
.vault-renew-n{ font-size:var(--type-lead); font-weight:600; position:relative; z-index:1; }
.vault-renew-w{ font-size:var(--type-body); color:var(--text-dim); flex:none; position:relative; z-index:1; }
:root[data-mode="light"] .vault-renew.hot .vault-renew-n{ font-weight:700; }

.vault-grid{ display:grid; grid-template-columns:repeat(auto-fill, minmax(min(100%, var(--tile-min)), 1fr));
  gap:var(--tile-gap); align-items:start; max-width:var(--tile-span); margin-bottom:var(--space-6); }

/* THE HOUSE PLAN.
   Translucent tiles on a grid, tilted a few degrees so it reads as a plan
   rather than as another list of cards. Deliberately restrained: the tilt is
   one transform on the container, so every tile stays a rectangle and the
   text inside it stays flat and legible. A real perspective transform would
   put the room names on a slant, which looks like a demo and reads like
   nothing. Reduced motion and narrow screens drop the tilt entirely. */
.house-plan{ display:grid; grid-template-columns:repeat(auto-fill, minmax(150px, 1fr));
  gap:var(--space-3); margin:var(--space-2) 0 var(--space-3); transform:rotateX(6deg); transform-origin:top center; }
.house-tile{ position:relative; min-height:92px; padding:var(--space-3) var(--space-4); border-radius:var(--radius-card); cursor:pointer;
  border:1px solid var(--glass-border);
  background:color-mix(in srgb, var(--accent) 7%, transparent);
  box-shadow:inset 0 1px 0 color-mix(in srgb, var(--text) 8%, transparent);
  transition:background var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out); }
.house-tile:hover{ background:color-mix(in srgb, var(--accent) 13%, transparent); transform:translateY(-2px); }
.house-tile-name{ font-size:var(--type-lead); font-weight:600; color:var(--text); }
.house-tile-sub{ font-size:var(--type-body); color:var(--text-dim); margin-top:var(--space-1); }
.house-tile-flag{ font-size:var(--type-label); color:var(--cat-orange-text, var(--text-dim)); margin-top:var(--space-2); }
/* "What needs doing", at the two scales the page speaks at: a badge on the
   room tile and a badge on the one thing the task is actually about. Same
   colour as a warranty flag on purpose — both are "you should look at
   this", and giving them two different colours would imply they differ in
   kind rather than in what kind of attention they are asking for. */
.house-tile-todo{ font-size:var(--type-label); color:var(--cat-orange-text, var(--text-dim)); margin-top:var(--space-hair); font-weight:600; }
.house-row-todo{ flex:none; font-size:var(--type-label); font-weight:600; color:var(--cat-orange-text, var(--text-dim));
  white-space:nowrap; }
.house-filters{ display:flex; flex-wrap:wrap; gap:var(--space-2); margin:var(--space-2) 0 var(--space-5); }
.house-filter{ font-size:var(--type-body); color:var(--text-dim); padding:var(--space-2) var(--space-3); border-radius:var(--radius-control);
  border:1px solid var(--glass-border); background:color-mix(in srgb, var(--text) 3%, transparent); }
.house-filter b{ color:var(--text); font-weight:600; }
@media (max-width:720px){ .house-plan{ transform:none; } }
@media (prefers-reduced-motion: reduce){
  .house-plan{ transform:none; }
  .house-tile:hover{ transform:none; }
}
.vault-item{ padding:var(--space-4); border-radius:var(--radius-card); cursor:pointer;
  border:1px solid var(--glass-border);
  background:color-mix(in srgb, var(--text) 3%, transparent);
  transition:border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out); }
.vault-item:hover{ border-color:var(--glass-border-hi); }
:root:not([data-mode="light"]) .vault-item:hover{ box-shadow:0 0 22px -6px var(--accent-glow); }
.vault-item-name{ font-size:var(--type-lead); font-weight:600; letter-spacing:-.005em; }
/* A definition list, because that is what these are. Two columns so the
   labels line up down the card and the eye can run past them. */
.vault-fields{ display:grid; grid-template-columns:auto 1fr; gap:var(--space-1) var(--space-3); margin:var(--space-3) 0 0;
  font-size:var(--type-body); }
.vault-fields dt{ color:var(--text-dim); white-space:nowrap; }
.vault-fields dd{ margin:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.vault-item-foot{ display:flex; align-items:baseline; justify-content:space-between;
  gap:var(--space-3); margin-top:var(--space-3); font-size:var(--type-body); color:var(--text-dim); }
.vault-cost{ font-family:var(--font-mono); }
.vault-due.hot{ color:var(--text); font-weight:600; }

/* "Not a purchase" — the no on a vault suggestion. Quiet until the row is
   under the pointer, because the common answer to a suggestion is the tick
   beside it and a second loud button would compete with it. Never hidden,
   though: opacity would take it away from the keyboard, so it is always
   there and always reachable by tab. */
.rcpt-no{ flex:none; align-self:center; cursor:pointer; white-space:nowrap;
  background:none; border:1px solid var(--glass-border); border-radius:var(--radius-tight);
  color:var(--text-faint); font-size:var(--type-label); padding:var(--space-1) var(--space-2); }
.rcpt-no:hover{ color:var(--text); border-color:var(--glass-border-hi); }
.rcpt-no:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

/* HOW OFTEN, in the vault form. Wraps rather than squeezing: five chips in a
   half-width column will not fit on one line on a laptop, and chips that
   shrink to fit stop being readable before they stop fitting. */
.vault-period{ display:flex; flex-wrap:wrap; gap:var(--space-2); margin-bottom:var(--space-hair); }

/* The vault page's own toolbar height. The shared header rules (flex-basis and
   min-width on the first column) stay beside .vault-head in app.css. */
#view-vault > .vault-head{ min-height:var(--space-16); }

/* =========================================================================
   A VIDEO GOING INTO THE VAULT, while it goes.

   AT THE END OF THE FILE, like the item-6 block above it: this stylesheet
   carries a :root override block thousands of lines below the rules it
   overrides, and the four-across fix lost to it silently three times before
   being moved here on 5 October. Last wins.

   WHY A BAR AT ALL. Every other attachment in this app is a few hundred
   kilobytes and done before the toast finishes animating. A 200MB video is
   minutes, and minutes of nothing moving is indistinguishable from broken,
   which is the failure this app cares about most. fetch() cannot report
   upload progress, so uploadVaultVideo uses XMLHttpRequest purely to be able
   to move this.
   ========================================================================= */
.vk-up{
  display:flex;
  align-items:center;
  gap:var(--space-3);
  margin:var(--space-3) 0 0;
}
.vk-up-bar{
  flex:1;
  min-width:0;
  height:6px;
  border-radius:var(--radius-pill);
  background:color-mix(in srgb, var(--text) 12%, transparent);
  overflow:hidden;
}
.vk-up-fill{
  display:block;
  height:100%;
  width:0;
  border-radius:var(--radius-pill);
  background:var(--accent);
  transition:width .2s ease;
}
/* The words carry the real information — the megabytes and the percentage —
   because a bar alone cannot say WHICH of the three steps is happening, and
   "Reading it", "Asking for somewhere to put it" and "Uploading 180 MB" are
   three different kinds of waiting. */
.vk-up-say{
  flex:none;
  font-size:var(--type-label);
  color:var(--text-dim);
  font-variant-numeric:tabular-nums;   /* or the percentage jitters as it counts */
}
/* A bar that animates its own width is fine; a bar that animates when he has
   asked the system for no animation is not. */
@media (prefers-reduced-motion:reduce){
  .vk-up-fill{ transition:none; }
}
