/*
 * The customer portal's own stylesheet.
 *
 * -- Why this file has to exist -----------------------------------------
 *
 * Same cause as public/css/operator.css: there is no bundler and no Tailwind
 * build in this application, deliberately, so the utility classes written on
 * our own Filament pages are not in Filament's compiled sheet -- it compiles
 * the utilities IT uses. Measured on this checkout: Filament v5 ships 848
 * `fi-*` classes and no bare utilities at all, so `grid`, `gap-3`,
 * `bg-primary-50`, `capitalize` and `rounded-lg` on the portal dashboard did
 * not resolve to something weak, they resolved to nothing.
 *
 * The difference from the operator console is who is looking. This is the
 * FIRST screen a customer sees after choosing a password. So this file does
 * not stop at a utility subset: it gives the page the product's own faces and
 * a small named vocabulary, and the Blade is written against that vocabulary
 * rather than against utility names that exist only here.
 *
 * -- Load order, corrected ----------------------------------------------
 *
 * operator.css:29-30 says it "loads AFTER Filament's stylesheet, so where both
 * define something ours wins". It does not: in
 * vendor/filament/filament/resources/views/components/layout/base.blade.php,
 * :66 is `@filamentStyles` and :68 is the theme link -- two lines LATER. The
 * conclusion survives for a better reason. Every rule in
 * vendor/filament/filament/dist/theme.css is inside a CSS cascade layer
 * (properties, theme, base, components, utilities), and an unlayered rule
 * outranks a layered one whatever the document order.
 *
 * So: NOTHING in this file may be wrapped in an @layer.
 *
 * The one exception is the inline `:root` block at base.blade.php:76-82,
 * which is unlayered AND later -- see the `:root:root` note below.
 *
 * -- Colour policy -------------------------------------------------------
 *
 * Structure (rules, muted text, badge grounds) comes from Filament's own
 * custom properties, so it follows the panel's dark-mode toggle instead of
 * pinning a second palette beside it. The brand accents that carry identity
 * are named `--cf-*` here and each is given an explicit dark counterpart,
 * because the marketing palette is light-only -- public/css/marketing.css has
 * no prefers-color-scheme rule anywhere -- and navy text on a near-black card
 * is what follows from pinning one without.
 *
 * Every value below is already in this repository. Nothing is invented.
 */

/* -- Faces --------------------------------------------------------------
   The same three self-hosted faces the marketing site uses, redeclared
   because marketing.css is loaded by exactly one file
   (resources/views/marketing/layout.blade.php:42) and a Filament panel
   inherits nothing from it. The .woff2 files are already in public/fonts.

   Only the weights this panel needs: Archivo 500/600 for display, Barlow
   400/500/600 for body, Plex Mono 400/500 for labels and identifiers. */

@font-face { font-family: Archivo; font-style: normal; font-weight: 500; font-display: swap;
  src: url("../fonts/archivo-500.woff2") format("woff2"); }
@font-face { font-family: Archivo; font-style: normal; font-weight: 600; font-display: swap;
  src: url("../fonts/archivo-600.woff2") format("woff2"); }

@font-face { font-family: Barlow; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/barlow-400.woff2") format("woff2"); }
@font-face { font-family: Barlow; font-style: normal; font-weight: 500; font-display: swap;
  src: url("../fonts/barlow-500.woff2") format("woff2"); }
@font-face { font-family: Barlow; font-style: normal; font-weight: 600; font-display: swap;
  src: url("../fonts/barlow-600.woff2") format("woff2"); }

@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/plexmono-400.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("../fonts/plexmono-500.woff2") format("woff2"); }

/*
 * `:root:root`, not `:root`.
 *
 * Filament emits its own UNLAYERED `:root { --font-family: 'Inter Variable';
 * --mono-font-family: ...; }` in an inline <style> after @filamentStyles
 * (base.blade.php:76-82). Same selector, same specificity, later in the
 * document -- so a plain `:root` here loses and the panel stays on Inter.
 * Doubling the pseudo-class takes this to (0,2,0) and it wins.
 *
 * The panel's ->font() API is deliberately NOT used. With a custom family and
 * no explicit provider it defaults to BunnyFontProvider
 * (vendor/filament/filament/src/Panel/Concerns/HasFont.php:83), which emits a
 * preconnect and a stylesheet from fonts.bunny.net -- a third-party origin,
 * which is the one thing this product promises it does not do.
 */
:root:root {
  --font-family: Barlow;
  --mono-font-family: "IBM Plex Mono";
}

/* -- Brand tokens, with the dark half stated ----------------------------
   Values from public/css/marketing.css:50-74. */

:root {
  --cf-display: Archivo, "Helvetica Neue", Arial, sans-serif;
  --cf-mono: "IBM Plex Mono", ui-monospace, Consolas, monospace;

  /* The lead heading colour: navy on light.                              */
  --cf-lead: #0B1F3F;
  /* Labels and kickers. brass-deep, because plain brass (#E0A233) is
     2.1:1 on a light ground -- marketing.css:56-57 states exactly this,
     and the site follows it: brass-deep on bone, brass on navy.          */
  --cf-kicker: #8A5D12;
  /* The rule down the side of a notice. A fill, never text.              */
  --cf-accent: #E0A233;
  /* Hairlines. Warm, so they belong to the bone rather than to a grey
     borrowed from somewhere else (marketing.css:68-69).                  */
  --cf-line: #E3E0D4;
  /* The "not yet" frame (marketing.css:280-291).                         */
  --cf-dashed: #B9C4D1;
}

/*
 * Dark mode is a class Filament stamps on <html>, not a media query -- the
 * panel's own toggle sets it, so matching on prefers-color-scheme alone leaves
 * a manually switched panel with light-mode text on a dark card. Same
 * reasoning as operator.css:100-105.
 *
 * The four values that cannot survive the swap and what replaces them: navy ->
 * Filament's lightest gray; brass-deep -> plain brass, which is the pairing
 * the marketing site already uses on its navy bands (marketing.css:197); both
 * hairlines -> Filament's grays, so they track the panel's own surfaces.
 */
.dark {
  --cf-lead: var(--gray-100);
  --cf-kicker: #E0A233;
  --cf-line: var(--gray-700);
  --cf-dashed: var(--gray-600);
}

/* -- OPTIONAL: square corners ------------------------------------------
 *
 * Zero radius is the loudest single signature in this design and the easiest
 * to lose by habit (marketing.css:24-26). Filament v5 draws every surface from
 * four radius tokens, so zeroing them squares sections, buttons, inputs and
 * dropdowns across this panel without one selector aimed at Filament's own
 * markup. The pills that must stay round -- avatars, Filament's own badges --
 * do not use these tokens: they carry a literal `border-radius:3.40282e38px`,
 * counted 19 times in theme.css. They are untouched.
 *
 * Usage counts read from vendor/filament/filament/dist/theme.css:
 * --radius-lg 107, --radius-xl 38, --radius-md 20, --radius-sm 2.
 *
 * NOT RENDERED. Nobody has looked at this in a browser. Delete this block to
 * keep Filament's radius; nothing else in this file depends on it.
 */
:root:root {
  --radius-sm: 0;
  --radius-md: 0;
  --radius-lg: 0;
  --radius-xl: 0;
}

/* -- The lead -----------------------------------------------------------
 *
 * One sentence per state, at the top of the section, in the display face.
 * The page's whole failure was that it had no lead: seven tenant states all
 * rendered the same four-cell grid, so "pending" arrived as a bare word in a
 * table of equal-weight facts.
 */

.cf-lead {
  font-family: var(--cf-display);
  font-weight: 600;
  font-size: 1.25rem;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--cf-lead);
  margin: 0 0 0.75rem;
  text-wrap: balance;
}

.cf-body {
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--gray-500);
  margin: 0 0 0.75rem;
  max-width: 45rem;
}

.cf-body:last-child { margin-bottom: 0; }
.cf-body strong { color: var(--cf-lead); font-weight: 600; }

/* -- Labels -------------------------------------------------------------
 *
 * The mono eyebrow from marketing.css:132-135, at the card's tighter tracking
 * (marketing.css:270). This one substitution -- a mono kicker instead of a
 * bold sans label -- does most of the work of making the page read as part of
 * the product rather than as an admin panel.
 */

.cf-key {
  display: block;
  font-family: var(--cf-mono);
  font-size: 0.68rem;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cf-kicker);
  margin-bottom: 0.3rem;
}

/* -- The facts grid -----------------------------------------------------
 *
 * Gap from the marketing card rhythm (1.1rem, marketing.css:263), which is
 * looser than an admin panel's default and is part of why the marketing site
 * does not read as one.
 */

.cf-facts {
  display: grid;
  gap: 1.1rem;
  margin: 1.5rem 0 0;
}

@media (min-width: 640px) {
  .cf-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.cf-facts > div { min-width: 0; }
.cf-facts dd { margin: 0; font-size: 0.95rem; color: var(--cf-lead); }

/* Identifiers are set in a fixed pitch because that is what they are, and
   because demo1 and demo2 are one glyph apart in a proportional face -- the
   same reason operator.css:146-147 gives. This is the one the customer
   copies. */
.cf-identifier {
  display: block;
  font-family: var(--cf-mono);
  font-size: 0.85rem;
  overflow-wrap: break-word;
}

/* A hostname that is reserved but not yet resolvable is not a link, and the
   reason is stronger than tidiness: cratonis.app is HSTS-preloaded at the TLD,
   so clicking through to a tenant whose certificate has not issued is a
   browser security interstitial with no HTTP fallback. Dimmed and stated,
   rather than clickable. */
.cf-identifier--reserved { color: var(--gray-500); }

.cf-meta {
  display: block;
  font-family: var(--cf-mono);
  font-size: 0.72rem;
  line-height: 1.45;
  letter-spacing: 0.02em;
  color: var(--gray-500);
  margin: 0.35rem 0 0;
}

/* -- State, as a badge rather than a word -------------------------------
 *
 * The class names and the state->colour mapping are taken from
 * operator.css:173-192 on purpose, so a customer and an operator looking at
 * the same tenant see the same colours. Two deliberate differences:
 *
 *   - squared, per the zero-radius rule (operator.css uses 9999px);
 *   - a `.dark` block, which operator.css does not have. Its badges sit on
 *     50-shade backgrounds in dark mode, because Filament's palette variables
 *     are emitted once with no dark variant. That is a real gap in the
 *     operator console. It is flagged, not fixed here.
 */

.cf-state {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 0;
  font-family: var(--cf-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  white-space: nowrap;
  background: var(--gray-100);
  color: var(--gray-700);
}

.cf-state--active { background: var(--success-50); color: var(--success-700); }
.cf-state--suspended,
.cf-state--failed { background: var(--danger-50); color: var(--danger-700); }
.cf-state--provisioning,
.cf-state--pending { background: var(--warning-50); color: var(--warning-700); }

.dark .cf-state { background: var(--gray-800); color: var(--gray-400); }
.dark .cf-state--active { background: var(--success-950); color: var(--success-400); }
.dark .cf-state--suspended,
.dark .cf-state--failed { background: var(--danger-950); color: var(--danger-400); }
.dark .cf-state--provisioning,
.dark .cf-state--pending { background: var(--warning-950); color: var(--warning-400); }

/* -- Notices ------------------------------------------------------------
 *
 * The brand has exactly one alert shape: a 3px brass left rule on the surface
 * colour, square, no wash and no icon, used for both success and information
 * (marketing.css:352-354 -- role="status" at signup-sent.blade.php:16 and
 * role="alert" at signup.blade.php:18-20 are the same component).
 *
 * The page previously used `bg-primary-50 rounded-lg`: a tinted rounded pill
 * in Filament's stock teal, which is neither the brand's shape nor a brand
 * colour. No background fill here -- inside a Filament section the surface is
 * already a card, and a second fill on top of it reads as a nested box.
 */

.cf-notice {
  border-left: 3px solid var(--cf-accent);
  padding: 0.75rem 0 0.75rem 1.15rem;
  font-size: 0.95rem;
  line-height: 1.5;
  font-weight: 500;
  color: var(--cf-lead);
  max-width: 45rem;
}

.cf-notice + .cf-notice { margin-top: 0.75rem; }

/* "Not yet" has its own frame in this design: a dashed outline on no fill --
   a card that is visibly the outline of a card. Saying "not yet" in the same
   weight as everything else is how a roadmap gets read as a product
   (marketing.css:280-291). Used here for a workspace still being built, and
   for plans that are not sellable. */
.cf-waiting {
  border: 1px dashed var(--cf-dashed);
  border-radius: 0;
  padding: 1.1rem 1.3rem;
  max-width: 45rem;
}

.cf-waiting .cf-body:last-child { margin-bottom: 0; }

/* -- Action rows -------------------------------------------------------- */
/* marketing.css:213 -- .cta-row. */

.cf-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  align-items: center;
  margin-top: 1.1rem;
}

.cf-actions form { margin: 0; }

/* -- Plans --------------------------------------------------------------
 *
 * The same grid and card as the pricing page (marketing.css:312-320), so a
 * customer who read the pricing page recognises what they are buying. What
 * this replaces was a row of identical buttons carrying a name and a price and
 * nothing about what the plan gives.
 */

.cf-plans {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15.5rem, 1fr));
  gap: 1.1rem;
  align-items: stretch;
  margin-top: 1.1rem;
}

.cf-plan {
  border: 1px solid var(--cf-line);
  border-radius: 0;
  padding: 1.4rem 1.3rem;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

/* One primary, the rest quiet -- the two-tier convention the pricing page
   already uses (.plan.featured, marketing.css:316). */
.cf-plan--featured { border-color: var(--cf-accent); }

/* The plan being billed. It outranks --featured, because "what I am paying
   for" is a fact about this customer and "what we would like you to buy" is
   not -- so a subscribed customer never sees a louder card than their own. */
.cf-plan--current {
  border-color: var(--cf-accent);
  border-width: 2px;
  padding: 1.3rem 1.2rem;
}

.cf-plan-badge {
  align-self: flex-start;
  background: var(--cf-accent);
  color: var(--cf-on-accent, #fff);
  font-family: var(--cf-mono, monospace);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.22rem 0.6rem;
}

/* Sits where the button would, so the cards stay the same height and the
   grid does not jump when a subscription starts. */
.cf-plan-note,
.cf-plan-action { margin-top: auto; }

.cf-plan-note {
  font-size: 0.85rem;
  color: var(--cf-muted, #5C6873);
  margin-bottom: 0;
}

.cf-plan-name {
  font-family: var(--cf-display);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--cf-lead);
}

.cf-plan-price {
  font-family: var(--cf-display);
  font-size: 2rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--cf-lead);
}

.cf-plan-price small {
  font-family: var(--font-family), sans-serif;
  font-size: 0.85rem;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--gray-500);
}

.cf-plan ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.4rem;
  font-size: 0.9rem;
  color: var(--gray-500);
}

.cf-plan ul li::before { content: "\2014 "; color: var(--cf-kicker); }

.cf-plan form { margin-top: auto; }
