/* ============================================================
   File:        devices.css
   Project:     StudioFlow (Grace Aerobics & Fitness Center)
   Developer:   Janvi Vakhariya — V Techno Labs
   Created:     2026-09-01  (updated 2026-09-07)
   Purpose:     Design system for Manage Devices — the three shared phone
                slots, who holds them, and how a slot is freed.
   Copyright:   © 2026 V Techno Labs. All rights reserved.
                Proprietary software developed by V Techno Labs.
   ============================================================

   Theme: "Sunset" — pink→peach→violet wash behind glass cards.
   Everything sits straight; colour does the funk.

   Prefix: sf-dev-, and nothing else. Never sf-dash- / sf-idash-, so this
   page cannot touch either dashboard and neither dashboard can touch it.

   Four things this file does differently from the supplied design, all of
   them because it now lives inside the StudioFlow app shell:

   1. The bar variables are bound to the shell's real bar heights
      (--appbar-h 56px, --tabbar-h 64px, from site.css :root) rather than
      to hard-coded numbers, and are then zeroed inside .sf-app — .sf-app
      already pads the body past both fixed bars, so reserving the same
      space again would leave a second empty bar's worth of gap.

   2. The ground is painted by a fixed backdrop behind the whole page
      instead of as a block behind the column. Manage Devices is an inner
      page, so the body ground is the app's plain grey; a gradient that
      stopped at the column edge would read as a coloured rectangle
      dropped on grey.

   3. container-type: inline-size is not declared. The design set it, but
      no @container query in this file ever reads it, and containment
      would make .sf-dev the containing block for the fixed backdrop in
      note 2, which would then cover only the column.

   4. .sf-dev-remove--off replaces the design's guarded "remove this
      phone" button. DevicesController refuses to remove the browser the
      admin is sitting on, so the row shows the action as unavailable and
      says why, rather than offering a button the server would bounce.

   The footer here is the rainbow rule only. The tagline and the credit
   under it come from the shared _SiteFooter partial the layout already
   renders, so the design's .sf-dev-foot-tag / -credit rules are left out —
   keeping them would say "Music on. Chaos off." twice on one screen.

   Icons: every .sf-dev-ico is a 20×20 slot for the app's own SVGs (28×28
   inside the empty state via .sf-dev-empty-ico, 16×16 chevrons via
   .sf-dev-go). currentColor applies. Archivo 400/600/700/800 is loaded
   once by _PwaHead, not here.
   ============================================================ */

.sf-dev {
  --sf-dev-wing: linear-gradient(90deg,#43a047,#d4b91e,#f57c00,#e53957,#c2185b,#7e57c2,#5c6f91);
  --sf-dev-ground: linear-gradient(165deg, #fdeef3 0%, #fde8d9 34%, #f3ecfa 70%, #e8f0fb 100%);
  /* Muted deepened from #6d6b58, which measured 4.05:1 against the darkest
     part of the shared ball-pit ground -- under the 4.5:1 minimum for any
     muted line that sits on the ground rather than inside a card. #615F4E
     measures 4.85:1 there and 6.45:1 on white. Deepening the ink was the fix,
     not a panel behind the text. */
  --sf-dev-ink: #2b2a1f; --sf-dev-muted: #615F4E;
  --sf-dev-pink: #c2185b;
  --sf-dev-card: #ffffff; --sf-dev-edge: rgba(43,42,31,.08);
  --sf-dev-line: rgba(43,42,31,.12);
  --sf-dev-good: #1d7a3f; --sf-dev-good-tint: #e3f3e8;
  --sf-dev-warn: #9a5b00; --sf-dev-warn-tint: #fdf0d7;
  --sf-dev-bad: #b3261e;  --sf-dev-bad-deep: #8c1d17; --sf-dev-bad-tint: #fdecea;
  --sf-dev-slot: linear-gradient(155deg, #6d7fa3, #46587e);  /* claimed slot block */
  --sf-dev-radius: 20px; --sf-dev-tap: 48px;

  /* The shell's real fixed bars, read from site.css :root. The fallbacks are
     the same 56/64 the design shipped with, so a standalone use of .sf-dev
     outside the shell still clears them. Zeroed below — see note 1. */
  --sf-dev-top-bar: var(--appbar-h, 56px); --sf-dev-bottom-bar: var(--tabbar-h, 64px);

  box-sizing: border-box; max-width: 640px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 16px;
  padding: calc(var(--sf-dev-top-bar) + 14px) 16px calc(var(--sf-dev-bottom-bar) + 26px + env(safe-area-inset-bottom, 0px));
  background: var(--sf-dev-ground);
  color: var(--sf-dev-ink);
  font-family: "Archivo", system-ui, sans-serif; font-size: 15px; line-height: 1.5;
  -webkit-tap-highlight-color: transparent;
}

/* Inside the app shell the layout has already done the spacing: .sf-app pads
   the body past both fixed bars, and .sf-content supplies the 1rem side gutter
   and caps the column at 640px. Repeating either would double it. */
.sf-app .sf-dev {
  --sf-dev-top-bar: 0px;
  --sf-dev-bottom-bar: 0px;
  padding-left: 0; padding-right: 0;
  background: transparent;
}

/* The sunset wash, painted across the whole viewport rather than behind the
   column (note 2). Fixed and out of flow, so it is not a flex item, and it
   does not scroll away on a long device list. It sits above the body's grey
   and below every card; the app bar and tab bar are fixed at z-index 20 with
   their own navy, so neither is touched. */
/* No page backdrop here any more. site.css paints ONE background on .sf-app for
   every signed-in page, so this sheet no longer paints its own: four stylesheets
   each drawing their own ground is exactly how Plans ended up tiled while Users
   ended up plain. The --sf-dev-ground variable above is kept for the standalone,
   outside-the-shell case documented at the top of this file. */

.sf-dev *, .sf-dev *::before, .sf-dev *::after { box-sizing: border-box; }
:where(.sf-dev a) { color: inherit; text-decoration: none; }
.sf-dev :focus-visible { outline: 2px solid var(--sf-dev-pink); outline-offset: 2px; }
.sf-dev-ico { display: inline-block; width: 20px; height: 20px; flex: none; }
.sf-dev-go { display: inline-block; width: 16px; height: 16px; flex: none; opacity: .7; }

/* ---------- top: back link + the rule, quietly ---------- */
.sf-dev-back {
  display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
  min-height: 44px; margin: -6px 0 -10px;
  font-size: 14px; font-weight: 800; color: var(--sf-dev-pink);
}
.sf-dev-back:active { text-decoration: underline; text-underline-offset: 3px; }
.sf-dev-back .sf-dev-go { transform: rotate(180deg); opacity: 1; }

.sf-dev-rule { margin: 0 2px; font-size: 14px; color: var(--sf-dev-muted); text-wrap: pretty; }
.sf-dev-rule strong { color: var(--sf-dev-ink); font-weight: 800; }

/* ============================================================
   SLOT CARD — the thing she came to see.
   Three physical slot blocks + one big count. Two states on the
   card: (default: slots free) and .sf-dev-slots--full.
   ============================================================ */
.sf-dev-slots {
  background: #ffffff;            /* solid over the shared background */
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 1.5px solid rgba(255,255,255,.9);
  border-radius: var(--sf-dev-radius);
  box-shadow: 0 14px 30px -16px rgba(194,24,91,.4);
  padding: 16px; position: relative; overflow: hidden;
}
.sf-dev-slots::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 5px; background: var(--sf-dev-wing); }

.sf-dev-slots-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 2px 0 12px; }
.sf-dev-slots-title { margin: 0; font-size: 12px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--sf-dev-muted); }

/* summary pill flips colour with the state */
.sf-dev-slots-pill {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 30px; padding: 0 12px; border-radius: 999px;
  font-size: 13px; font-weight: 800; white-space: nowrap;
  background: var(--sf-dev-good-tint); color: var(--sf-dev-good);
}
.sf-dev-slots--full .sf-dev-slots-pill { background: var(--sf-dev-warn-tint); color: var(--sf-dev-warn); }

.sf-dev-count { display: flex; align-items: baseline; gap: 8px; margin: 0 0 12px; }
.sf-dev-count-big { font-size: 40px; font-weight: 800; line-height: 1; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.sf-dev-count-of { font-size: 15px; font-weight: 700; color: var(--sf-dev-muted); }

/* the three slots, drawn as objects */
.sf-dev-slotrow { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 10px; }
.sf-dev-slot {
  min-height: 74px; border-radius: 16px; padding: 10px 10px 8px;
  display: flex; flex-direction: column; justify-content: space-between; gap: 4px;
  min-width: 0;
}
.sf-dev-slot-n { font-size: 10px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; opacity: .75; }
.sf-dev-slot-who { font-size: 13px; font-weight: 800; text-transform: capitalize; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* claimed: solid slate block, white text — reads "occupied" */
.sf-dev-slot--used { background: var(--sf-dev-slot); color: #fff; border: 1px solid rgba(255,255,255,.3); box-shadow: 0 8px 16px -9px rgba(20,10,35,.55); }
/* this phone's slot gets the pink seam so the card and the list agree */
.sf-dev-slot--you { background: linear-gradient(155deg, #e0447a, #98123f); }
/* free: dashed outline, airy — reads "empty socket" */
.sf-dev-slot--free { border: 2px dashed rgba(43,42,31,.28); color: var(--sf-dev-good); background: transparent; justify-content: center; align-items: center; }
.sf-dev-slot--free .sf-dev-slot-free-label { font-size: 12px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
/* full state: the free styling never appears; give used blocks a warmer edge */
.sf-dev-slots--full .sf-dev-slot--used:not(.sf-dev-slot--you) { border-color: rgba(255,209,102,.65); }

.sf-dev-slots-note { margin: 12px 0 0; font-size: 13px; color: var(--sf-dev-muted); }
.sf-dev-slots--full .sf-dev-slots-note { color: var(--sf-dev-warn); font-weight: 600; }

/* ---------- section heading ---------- */
.sf-dev-h { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin: 2px 2px -6px; }
.sf-dev-h-title { margin: 0; font-size: 15px; font-weight: 800; }
.sf-dev-h-side { font-size: 13px; font-weight: 700; color: var(--sf-dev-muted); white-space: nowrap; }

/* ============================================================
   DEVICE LIST
   Same-name problem: every row carries (a) its slot number chip
   and (b) a short device code — the LAST 4 of the stored device
   tag, e.g. "·B7F2" — plus the full registered date AND time.
   Two "Chrome on Windows" rows are never ambiguous again.
   ============================================================ */
.sf-dev-card {
  background: #ffffff;            /* solid over the shared background */
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 1.5px solid rgba(255,255,255,.9);
  border-radius: var(--sf-dev-radius);
  box-shadow: 0 14px 30px -16px rgba(194,24,91,.4);
  padding: 4px 16px;
}
.sf-dev-row {
  display: grid; grid-template-columns: 34px minmax(0,1fr) auto;
  align-items: center; column-gap: 12px; row-gap: 2px;
  padding: 13px 0; border-top: 1px solid var(--sf-dev-line);
}
.sf-dev-row:first-child { border-top: 0; }
/* the --you row stacks: text gets the full width, the action drops below */
.sf-dev-row--you { grid-template-columns: 34px minmax(0,1fr); }
.sf-dev-row--you .sf-dev-remove { grid-column: 2; grid-row: auto; justify-self: start; margin-top: 8px; }

/* slot number chip — ties the row to the slot blocks above */
.sf-dev-row-slot {
  grid-row: span 2; align-self: start; margin-top: 2px;
  width: 34px; height: 34px; border-radius: 10px;
  display: grid; place-items: center;
  background: var(--sf-dev-slot); color: #fff;
  font-size: 13px; font-weight: 800; font-variant-numeric: tabular-nums;
}
.sf-dev-row--you .sf-dev-row-slot { background: linear-gradient(155deg, #e0447a, #98123f); }

.sf-dev-row-main { min-width: 0; }
.sf-dev-row-name { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-width: 0; font-size: 15px; font-weight: 800; margin: 0; }
.sf-dev-row-name-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* the disambiguator: short device code, always visible, mono */
.sf-dev-code {
  flex: none; padding: 1px 7px; border-radius: 7px;
  background: rgba(43,42,31,.07); color: var(--sf-dev-muted);
  font-family: ui-monospace, "Cascadia Mono", Menlo, monospace;
  font-size: 11.5px; font-weight: 600; letter-spacing: .04em;
}

/* "this phone" — unmistakable: pink pill + pink row seam */
.sf-dev-you-pill {
  flex: none; display: inline-flex; align-items: center; gap: 5px;
  min-height: 24px; padding: 0 9px; border-radius: 999px;
  background: var(--sf-dev-pink); color: #fff;
  font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
}
.sf-dev-row--you { box-shadow: inset 3px 0 0 var(--sf-dev-pink); }
.sf-dev-row--you > * { transform: translateX(6px); }

.sf-dev-row-sub { margin: 1px 0 0; font-size: 13px; color: var(--sf-dev-muted); }
.sf-dev-row-sub strong { color: var(--sf-dev-ink); font-weight: 700; text-transform: capitalize; }
/* registered line: date AND time — part of telling twins apart */
.sf-dev-row-when { margin: 0; font-size: 12.5px; color: var(--sf-dev-muted); font-variant-numeric: tabular-nums; }

/* per-row remove: quiet outline, red ink — deliberate but not alarming */
.sf-dev-remove {
  grid-column: 3; grid-row: 1 / span 2; align-self: center;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 44px; padding: 0 14px; border-radius: 12px; cursor: pointer;
  border: 1.5px solid rgba(179,38,30,.35); background: transparent;
  color: var(--sf-dev-bad); font-family: inherit; font-size: 13.5px; font-weight: 800; white-space: nowrap;
}
.sf-dev-remove:active { background: var(--sf-dev-bad-tint); }
/* Remove is a POST, so the button arrives wrapped in a form that carries the
   antiforgery token. The form takes the grid cell the design gave the button —
   safer than display:contents, which some browsers still drop from the
   accessibility tree — and the button simply fills it. */
.sf-dev-remove-form { margin: 0; grid-column: 3; grid-row: 1 / span 2; align-self: center; }

/* On the admin's own phone the action is not available at all: the controller
   refuses it so she cannot end her own session and possibly lock the studio
   out. Shown as a flat, unclickable chip rather than a button — nothing here
   should invite a tap the server would only bounce. See note 4 in the header. */
.sf-dev-remove--off {
  border-color: transparent; background: rgba(43,42,31,.07);
  color: var(--sf-dev-muted); cursor: default;
}

/* caution line under the current device row */
.sf-dev-row-warn { grid-column: 2; margin: 4px 0 0; font-size: 12px; font-weight: 600; color: var(--sf-dev-bad-deep); }

/* The other action, offered on the row that raises the question: Remove frees
   a slot, Deactivate closes an account, and the two are confused often enough
   to be worth one line of link here. Sits under the row's text in column 2,
   the same lane as the caution line above, so it reads as a footnote to the
   row rather than as a second button competing with Remove. */
.sf-dev-row-alt {
  grid-column: 2; justify-self: start;
  display: inline-flex; align-items: center;
  min-height: 32px; margin-top: 2px;
  font-size: 12.5px; font-weight: 700; color: var(--sf-dev-pink);
  text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: rgba(194,24,91,.35);
}
.sf-dev-row-alt:active { text-decoration-color: currentColor; }

/* the same escape hatch in the page's opening rule */
.sf-dev-rule-link { font-weight: 800; color: var(--sf-dev-pink); text-decoration: underline; text-underline-offset: 3px; }

/* ---------- empty state ---------- */
.sf-dev-empty {
  background: #ffffff;            /* solid over the shared background */
  border: 2px dashed rgba(43,42,31,.22); border-radius: var(--sf-dev-radius);
  padding: 28px 18px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.sf-dev-empty-ico { display: inline-block; width: 28px; height: 28px; color: var(--sf-dev-muted); }
.sf-dev-empty-title { margin: 0; font-size: 16px; font-weight: 800; }
.sf-dev-empty-sub { margin: 0; max-width: 30ch; font-size: 13.5px; color: var(--sf-dev-muted); text-wrap: pretty; }

/* ============================================================
   RESET ALL — weightier than a row remove: its own bordered
   zone at the end, headline + consequence spelled out, solid
   deep-red full-width action. Serious, not shouting.
   ============================================================ */
.sf-dev-danger {
  border: 1.5px solid rgba(179,38,30,.3);
  border-radius: var(--sf-dev-radius);
  background: var(--sf-dev-bad-tint);
  padding: 16px;
}
.sf-dev-danger-title { margin: 0 0 4px; display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 800; color: var(--sf-dev-bad-deep); }
.sf-dev-danger-sub { margin: 0 0 12px; font-size: 13.5px; color: #7a3733; text-wrap: pretty; }
/* the reset form wraps the full-width button, so it adds no box of its own */
.sf-dev-danger-form { margin: 0; }
.sf-dev-danger-btn {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; min-height: var(--sf-dev-tap); border: 0; border-radius: 14px; cursor: pointer;
  background: linear-gradient(155deg, #c4372e, var(--sf-dev-bad-deep));
  color: #fff; font-family: inherit; font-size: 15px; font-weight: 800;
  box-shadow: 0 12px 24px -12px rgba(140,29,23,.7);
}
.sf-dev-danger-btn:active { transform: translateY(1px); filter: brightness(.94); }

/* ---------- footer ---------- */
.sf-dev-foot { text-align: center; padding: 2px 2px 0; }
.sf-dev-wingbar { height: 4px; border: 0; width: 132px; margin: 0 auto 12px; border-radius: 999px; background: var(--sf-dev-wing); }
