/* ═══════════════════════════════════════════════════════════════════════════
   The two views — the whole stylesheet half of the feature. See role.js.
   ═══════════════════════════════════════════════════════════════════════════

   Chess Bender shows a subscriber's screens and an operator's screens in the same
   place. The customer's view is the DEFAULT for everyone, administrators
   included, so the app can be looked at the way it will actually be sold.

   A page opts in with two tags:

     <link rel="stylesheet" href="role.css">
     <script src="role.js" defer></script>

   and then marks whatever is operator-only with `data-admin-only`.

   Written as :not() rather than "hide, then un-hide for admins" on purpose. The
   un-hide version has to guess a `display` to restore, and gets it wrong for
   every flex row and grid panel in this app. This way an administrator's markup
   matches no rule at all and styles exactly as it did before any of this
   existed.

   And because the attribute is ABSENT until role.js has an answer, the
   customer's view is what renders first. A page that flashed its admin controls
   and then took them away would defeat the point.

   This decides what is DRAWN. The server decides what is allowed, from the same
   session — see isAdmin(event) in main.js and the /auth routes.
   ═══════════════════════════════════════════════════════════════════════════ */

html:not([data-viewing-as="admin"]) [data-admin-only] { display: none !important; }
html[data-viewing-as="admin"] [data-user-only] { display: none !important; }

/* ── the switch ────────────────────────────────────────────────────────────
   The --ui-* variables come from theme.css. /app/ has its own stylesheet and
   does not define them, hence the fallbacks — that page has no switch today,
   but an unstyled button appearing there later would be a bad surprise. */

.viewswitch {
  font: inherit;
  font-size: 0.75rem;
  line-height: 1;
  padding: 0.375rem 0.625rem;
  border: 1px solid var(--ui-line, #2f3244);
  border-radius: var(--ui-radius, 0.5rem);
  background: var(--ui-btn, #262a3d);
  color: var(--ui-dim, #949ab0);
  cursor: pointer;
  white-space: nowrap;
}
@media (hover: hover) {
  .viewswitch:hover:not(:disabled) {
    background: var(--ui-btn-hover, #333750);
    color: var(--ui-text, #eef0f7);
  }
}
.viewswitch:disabled { opacity: .6; cursor: default; }

/* In the admin view the switch is the way back, so it reads as active rather
   than as one more grey link. */
.viewswitch[data-mode="admin"] {
  border-color: var(--ui-accent, #7c6cf2);
  color: var(--ui-text, #eef0f7);
}

/* An admin who forgets which view they are in turns every "this is broken for
   users" into a false alarm. This is the cheapest possible cure. */
.viewswitch-tag {
  font-size: max(0.625rem, var(--text-min)); /* 10px */
  font-weight: 700;
  letter-spacing: .08em;
  padding: 0.25rem 0.4375rem;
  margin-right: 0.5rem;
  border-radius: 62.4375rem;
  background: var(--ui-accent, #7c6cf2);
  color: var(--ui-accent-text, #fff);
  white-space: nowrap;
}

[data-view-switch] { display: inline-flex; align-items: center; }

/* ── who you are signed in as, and Sign out ─────────────────────────────────
   The address is there so switching accounts to test something can be verified
   at a glance rather than by remembering. It is the one place in the app that
   prints an email address on screen, and it prints only your own. */
[data-account-switch] { display: inline-flex; align-items: center; gap: 0.5rem; }
[data-account-switch][hidden] { display: none; }

.accountwho {
  font-size: max(0.6875rem, var(--text-min)); /* 11px */
  color: var(--ui-dim, #949ab0);
  /* Enough to tell two accounts apart, not enough to push the shell bar past
     the window. The whole address is in the button's tooltip. */
  max-width: 17ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.accountout {
  font: inherit;
  font-size: 0.75rem;
  line-height: 1;
  padding: 0.375rem 0.625rem;
  border: 1px solid var(--ui-line, #2f3244);
  border-radius: var(--ui-radius, 0.5rem);
  background: transparent;
  color: var(--ui-dim, #949ab0);
  cursor: pointer;
  white-space: nowrap;
}
@media (hover: hover) {
  .accountout:hover:not(:disabled) {
    background: var(--ui-btn-hover, #333750);
    color: var(--ui-text, #eef0f7);
  }
}
.accountout:disabled { opacity: .6; cursor: default; }
[data-view-switch][hidden] { display: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   Pro features, locked
   ═══════════════════════════════════════════════════════════════════════════

   Mark a control `data-pro` and role.js does the rest: for an account that is
   paying, nothing at all happens; for one that is not, this gold treatment and
   a click that goes to the Pro tab.

   Shown rather than hidden, deliberately, and that is José's instruction:
   *"Free users should still see the options, but they should have a gold border
   with a Pro label."* A feature that is simply absent sells nothing and teaches
   nobody that it exists.

   NONE OF THIS IS THE PAYWALL. Every one of these features is refused in the
   server process too — `mustBePro` in main.js. This is what a customer sees;
   that is what a customer cannot get past.

   `outline` and not `border`, so nothing here changes a layout: an outline is
   drawn outside the box and takes no space, which means a locked panel is
   exactly the size of an unlocked one and a tab bar does not reflow the moment
   somebody's subscription lapses. */

.is-prolocked {
  position: relative;
  outline: 1px solid var(--pro-gold, #e3b341);
  outline-offset: 2px;
  border-radius: var(--ui-radius, 0.5rem);
  cursor: pointer;
}

/* Dimmed through the CHILDREN rather than the element, because opacity on the
   element would take the badge down with it — and the badge is the one part
   that has to stay legible. */
.is-prolocked > *:not(.probadge) { opacity: .55; }

/* A control with no element children of its own — a plain <button> whose whole
   content is a text node — cannot be dimmed that way, so it is dimmed here. */
.is-prolocked { color: var(--ui-dim, #949ab0); }

/* THE BADGE IS A PSEUDO-ELEMENT, and that is not a shortcut — it is the fix.
   role.js used to append a <span class="probadge">, and half the controls here
   rewrite their own label: `Intense Mode (30)` is assigned through
   `textContent` whenever the counts change, which threw the appended badge
   away and left a gold outline with nothing in it. Nothing a page does to its
   own content can remove an ::after. */
.is-prolocked::after {
  content: 'PRO';
  position: absolute;
  top: -0.5625rem;
  right: 0.5rem;
  z-index: 2;
  font: 700 max(0.5625rem, var(--text-min))/1 var(--ui-font, system-ui, sans-serif); /* 9px */
  letter-spacing: .1em;
  padding: 0.25rem 0.375rem;
  border-radius: 62.4375rem;
  background: var(--pro-gold, #e3b341);
  color: var(--pro-gold-text, #1b1405);
  pointer-events: none;
  white-space: nowrap;
  opacity: 1;
}

/* Somewhere too small or too tightly packed for a badge hanging off the top
   corner — a tab in a tab bar, a checkbox line. `data-pro="inline"` puts it
   after the text instead, where it reads as part of the label. */
[data-pro="inline"].is-prolocked::after {
  position: static;
  display: inline-block;
  margin-left: 0.4375rem;
  vertical-align: middle;
}
[data-pro="inline"].is-prolocked { outline-offset: 1px; }

/* A <summary> is a list-item by default, so ::after lands after the marker in
   a way that reads oddly; making it a block gives the badge a normal line. */
summary.is-prolocked { list-style-position: outside; }

/* The one thing that must never be dimmed into unreadability is the reason it
   is dimmed. A locked control says what it is on hover. */
@media (hover: hover) { .is-prolocked:hover { outline-width: 2px; } }
