/* ==========================================================================
   Sakis Player — design system.
   Shared by all three areas: the public site, the customer area (/my) and the
   staff portal. Everything is driven by the tokens below, so a colour change
   here lands everywhere at once.

   Two naming schemes are intentionally kept in sync: the original short names
   (--ink, --panel, --line, --brand) that the existing markup uses, and the
   longer descriptive ones (--text, --surface, --border, --gold) used by the
   newer public-site components. They are aliases, not separate colours.
   ========================================================================== */
:root{
  /* surfaces */
  --bg:#0A0D12;
  --panel:#12161D;          --surface:#12161D;
  --panel-2:#0E1219;                              /* insets: sidebar, inputs  */
  --surface-2:#171C24;                            /* raised: hover, stripes   */
  --line:#232A36;           --border:#232A36;
  --line-soft:#1B212B;      --border-soft:#1B212B;

  /* text */
  --ink:#EDEFF2;            --text:#EDEFF2;
  --muted:#8891A0;          --text-muted:#8891A0;
  --faint:#5C6472;          --text-faint:#5C6472;

  /* accents */
  --brand:#F2A93B;          --gold:#F2A93B;
  --brand-2:#FFCE7A;        --gold-2:#FFCE7A;
  --brand-ink:#231603;
  --brand-soft:rgba(242,169,59,.10);              --gold-soft:rgba(242,169,59,.10);
  --brand-line:rgba(242,169,59,.30);
  --teal:#35D0C0;           --teal-soft:rgba(53,208,192,.10);
  --teal-line:rgba(53,208,192,.25);
  --green:#3DDC97; --amber:#F0B24A; --red:#EF6B6B; --blue:#6EA8FF;

  --radius:16px;
  --radius-sm:10px;

  --font-body:'Inter',system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
  --font-display:'Sora',var(--font-body);
  --font-mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--bg);color:var(--ink);
  font:15px/1.55 var(--font-body);
  -webkit-font-smoothing:antialiased;
}
a{color:var(--blue);text-decoration:none}
h1,h2,h3,h4{margin:0 0 .2em;font-family:var(--font-display);letter-spacing:-.01em}
h1,h2{font-weight:700}
svg{display:block}
.muted{color:var(--muted)}
.small{font-size:.82em}
.mono,.mono-line{font-family:var(--font-mono)}
.truncate{max-width:320px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* --- shell --- */
/* minmax(0,1fr), not 1fr: a plain `1fr` track refuses to shrink below its content's own
   minimum width, so one wide table pushes the whole work area past the window and the page
   scrolls sideways. minmax(0,…) lets the column shrink and the content wrap inside it. */
.shell{display:grid;grid-template-columns:240px minmax(0,1fr);min-height:100vh}
.sidebar{background:var(--panel-2);border-right:1px solid var(--line-soft);padding:22px 16px;display:flex;flex-direction:column;gap:22px}
.brand{display:flex;align-items:center;gap:12px}
/* Holds the logo. No background of its own — the mark is gold on transparent, so it reads
   on the sidebar and on the login card without a tile behind it. */
.brand-mark{width:44px;height:44px;border-radius:12px;display:grid;place-items:center;overflow:hidden;flex:0 0 auto}
.brand-mark img{width:100%;height:100%;object-fit:contain;display:block}
.brand-mark.big{width:64px;height:64px;margin:0 auto}
.brand strong{display:block;font-family:var(--font-display)}
.brand span{color:var(--muted);font-size:.8em}
.sidebar nav{display:flex;flex-direction:column;gap:4px}
.sidebar nav a{padding:9px 12px;border-radius:var(--radius-sm);color:var(--muted);transition:background .15s,color .15s}
.sidebar nav a:hover{background:var(--surface-2);color:var(--ink)}
.sidebar nav a.active{background:linear-gradient(180deg,var(--brand-2),var(--brand));color:var(--brand-ink);font-weight:600}
.signout{margin-top:auto;display:flex;flex-direction:column;gap:8px}
.whoami span{display:block;font-weight:600}
.whoami small{color:var(--muted)}
.signout button{background:var(--surface);color:var(--ink);border:1px solid var(--line);padding:8px;border-radius:var(--radius-sm);cursor:pointer;transition:border-color .15s,color .15s}
.signout button:hover{border-color:var(--red);color:var(--red)}

/* The work area uses the window it is given. The old fixed 1200px cap left a third of a
   wide screen black while squeezing the tables next to it into columns two characters wide.
   Reading blocks get their own measure below, where a long line would actually hurt. */
.content{padding:26px 30px;width:100%;max-width:1680px;margin:0 auto;min-width:0}
/* Same reason as .shell: every box between the window and a table must be allowed to shrink. */
.panel,.table-wrap{min-width:0}
.topbar{display:flex;justify-content:space-between;align-items:flex-end;margin-bottom:20px}
.eyebrow{color:var(--muted);text-transform:uppercase;letter-spacing:.08em;font-size:.72em;margin:0 0 2px}

/* --- panels --- */
.panel{background:var(--panel);border:1px solid var(--line-soft);border-radius:var(--radius);padding:20px;margin-bottom:20px}
.panel.compact{padding:18px}
.panel.two-column{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.4fr);gap:24px;align-items:start}
/* Explanatory text keeps a readable line length instead of stretching across the window. */
.panel.two-column>div p{max-width:62ch}
.notice-panel{background:var(--panel-2);color:var(--muted)}
.section-heading{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px}
.btn-link{color:var(--brand);font-size:.85em}

/* --- metrics --- */
.metrics-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:14px;margin-bottom:20px}
.metric{background:var(--panel);border:1px solid var(--line-soft);border-radius:var(--radius);padding:16px 18px;transition:border-color .15s}
.metric:hover{border-color:var(--line)}
/* The cards are links now: they must not inherit link colour or underline, and they need a
   visible affordance so it is obvious there is something behind the number. */
a.metric{display:block;color:inherit;text-decoration:none;cursor:pointer}
a.metric:hover{border-color:var(--brand-line);background:var(--surface-2);transform:translateY(-1px)}
a.metric:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
a.metric:active{transform:translateY(0)}
/* The card whose group the list is currently showing. */
a.metric.on{border-color:var(--brand);background:var(--brand-soft)}
a.metric span::after{content:" 92";opacity:0;transition:opacity .15s}
a.metric:hover span::after{opacity:.55}

/* Filter chips above a list. */
.filter-chips{display:flex;flex-wrap:wrap;gap:8px;margin:-4px 0 14px}
.filter-chips .chip{
  display:inline-block;padding:5px 12px;border-radius:999px;
  border:1px solid var(--line-soft);background:var(--panel-2);
  color:var(--muted);font-size:.82em;text-decoration:none;transition:border-color .15s,color .15s,background .15s;
}
.filter-chips .chip:hover{border-color:var(--line);color:var(--ink)}
.filter-chips .chip.on{border-color:var(--brand-line);background:var(--brand-soft);color:var(--brand)}
.metric span{color:var(--faint);font-size:.8em;text-transform:uppercase;letter-spacing:.05em}
.metric strong{display:block;font-family:var(--font-display);font-size:2em;font-weight:700;margin-top:6px}
.metric.green strong{color:var(--green)}.metric.teal strong{color:var(--teal)}
.metric.amber strong{color:var(--amber)}.metric.red strong{color:var(--red)}.metric.blue strong{color:var(--blue)}

/* --- forms --- */
/* A form is not a table: fields stop growing where they stop being comfortable to fill in,
   however wide the window is. */
.form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;align-items:end;max-width:820px}
/* A form that carries a table needs the room a table needs; 820px is for forms of short fields. */
.form-grid.full{max-width:none}
.form-grid .wide{grid-column:1/-1}
label{display:flex;flex-direction:column;gap:6px;font-size:.85em;color:var(--muted)}
input,select,textarea{background:var(--panel-2);border:1px solid var(--line);color:var(--ink);border-radius:var(--radius-sm);padding:10px 12px;font:inherit;width:100%}
/* A tick or a radio is a fixed-size control, not a field that fills its line — without this
   the rule above stretches it across its whole label and pushes the wording out of the box. */
input[type=checkbox],input[type=radio]{width:auto;flex:0 0 auto}
/* The list a <select> drops open is drawn by the operating system, not by this stylesheet.
   Telling it the page is dark is what stops it opening as white text on white. */
select{color-scheme:dark}
select option{background:var(--panel-2);color:var(--ink)}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--brand)}
button{font:inherit}
button.primary{
  background:linear-gradient(180deg,var(--brand-2),var(--brand));color:var(--brand-ink);
  border:0;padding:11px 18px;border-radius:var(--radius-sm);
  font-family:var(--font-display);font-weight:700;cursor:pointer;align-self:end;
  transition:transform .15s,box-shadow .15s;
}
button.primary:hover{transform:translateY(-1px);box-shadow:0 10px 24px rgba(242,169,59,.28)}
button.mini,a.mini{display:inline-block;background:var(--panel-2);border:1px solid var(--line);color:var(--ink);padding:6px 10px;border-radius:8px;cursor:pointer;font-size:.82em;text-decoration:none;line-height:1.2;transition:border-color .15s,color .15s}
button.mini:hover,a.mini:hover{border-color:var(--brand)}
button.mini.danger:hover{border-color:var(--red);color:var(--red)}
/* Four buttons in one cell: they wrap onto a second line rather than forcing the whole
   table wider than the window. */
.row-actions{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.mini-info{width:auto}
.mini-info td{padding:6px 18px 6px 0;border:0}

/* --- tables --- */
.table-wrap{overflow-x:auto}

/* Below this width a ten-column table cannot be read, only scrolled — so it stops being a table.
   Each row becomes a card with its own labels, which fits any screen and hides no control. The
   labels come from the table's own headers, filled in by the layout, so this applies to every
   table in the portal without any of them being rewritten. */
@media (max-width: 1000px){
  .table-wrap{overflow-x:visible}
  .table-wrap table,
  .table-wrap tbody,
  .table-wrap tr,
  .table-wrap td{display:block;width:100%}
  .table-wrap thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  .table-wrap tr{
    border:1px solid var(--line-soft);border-radius:var(--radius-sm);
    background:var(--panel-2);margin-bottom:12px;padding:4px 0;
  }
  /* Label above the value, both full width. A side-by-side grid would fight any cell that
     holds more than one thing — and several of them now do. */
  .table-wrap td{border:0;padding:7px 14px}
  .table-wrap td::before{
    content:attr(data-label);display:block;
    color:var(--faint);font-size:.74em;font-weight:600;
    text-transform:uppercase;letter-spacing:.05em;margin-bottom:2px;
  }
  /* The buttons are the card's footer, not a labelled field. Keyed on .row-actions rather than
     the last cell, because in several tables the last cell is ordinary data that still needs
     its label. */
  .table-wrap td.row-actions{
    display:flex;flex-wrap:wrap;gap:8px;
    border-top:1px solid var(--line-soft);margin-top:4px;padding-top:12px;
  }
  .table-wrap td.row-actions::before,
  .table-wrap td[data-label=""]::before,
  .table-wrap td.empty::before{display:none}
  .table-wrap td.empty{text-align:left}
}


table{width:100%;border-collapse:collapse;font-size:.9em}
/* break-word, never `anywhere`: `anywhere` tells the browser a cell may be one character wide,
   so the table happily shrinks a column until "Edit" reads "Ed / it" and a MAC breaks mid-octet.
   break-word still rescues a genuinely unbreakable string, but keeps a word's width as the
   minimum the column may claim. */
th,td{text-align:left;padding:10px 12px;border-bottom:1px solid var(--line-soft);overflow-wrap:break-word}
/* A control's label, a badge and an address are single units — they never wrap. */
.mono-line{white-space:nowrap}
.status,.tag,.chip,.pill,button.mini,a.mini,.btn-link{white-space:nowrap}
td.mac,small.mac{white-space:nowrap}
/* The opposite case, and the only place `anywhere` is right: a cell holding a machine string —
   a payment session id, an IPv6 address — that is one word hundreds of pixels wide. Without
   this the column demands that width and drags the table past the panel. */
.wrap-any{overflow-wrap:anywhere}
/* Second line of a merged cell: the detail that used to need a column of its own. */
.sub{display:block;color:var(--faint);font-size:.82em;margin-top:3px}
th{color:var(--faint);font-weight:600;font-size:.82em;text-transform:uppercase;letter-spacing:.04em}
tbody tr:hover{background:var(--surface-2)}
.row-actions form{display:inline}
.empty{color:var(--muted);text-align:center;padding:22px}

.status{display:inline-block;padding:3px 10px;border-radius:999px;font-size:.78em;font-weight:600}
.status.active{background:rgba(61,220,151,.15);color:var(--green)}
.status.trial{background:var(--teal-soft);color:var(--teal)}
.status.expired{background:rgba(240,178,74,.15);color:var(--amber)}
.status.suspended{background:rgba(239,107,107,.15);color:var(--red)}
/* A device that reached its provider only because our server asked on its behalf. Not a fault,
   so not red; not the outcome we want either, so not green. */
.status.relayed{background:rgba(240,178,74,.15);color:var(--amber)}
.tag{background:var(--panel-2);border:1px solid var(--line);border-radius:6px;padding:2px 8px;font-size:.78em}

/* --- flash --- */
.flash{padding:12px 16px;border-radius:var(--radius-sm);margin-bottom:16px;font-size:.9em}
.flash-success{background:rgba(61,220,151,.12);color:var(--green);border:1px solid rgba(61,220,151,.3)}
.flash-error{background:rgba(239,107,107,.12);color:var(--red);border:1px solid rgba(239,107,107,.3)}
.flash-info{background:rgba(110,168,255,.12);color:var(--blue);border:1px solid rgba(110,168,255,.3)}

/* --- login --- */
.login-body{display:grid;place-items:center;min-height:100vh}
.login-card{background:var(--panel);border:1px solid var(--line);border-radius:18px;padding:34px;width:360px;text-align:center}
.login-card h1{margin-top:16px}
.login-card form{display:flex;flex-direction:column;gap:14px;margin-top:20px;text-align:left}
.login-card button{margin-top:6px}

@media(max-width:820px){
  .shell{grid-template-columns:1fr}
  .sidebar{flex-direction:row;flex-wrap:wrap;align-items:center}
  .sidebar nav{flex-direction:row;flex-wrap:wrap}
  .signout{margin:0}
  .panel.two-column{grid-template-columns:1fr}
  .form-grid{grid-template-columns:1fr}
}

/* --- confirmation cards (device claim/activate) --- */
.confirm-lead{max-width:60ch;margin-bottom:4px}
.confirm-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:18px}
.confirm-solo{max-width:540px;margin-top:18px}
.confirm-card{background:var(--panel-2);border:1px solid var(--line-soft);border-radius:12px;padding:4px 18px 12px}
.confirm-card h4{margin:0;padding:13px 0;font-size:.74em;text-transform:uppercase;letter-spacing:.07em;color:var(--faint);font-weight:700;border-bottom:1px solid var(--line-soft)}
.kv{display:flex;justify-content:space-between;gap:18px;align-items:baseline;padding:10px 0;border-bottom:1px solid var(--line-soft)}
.kv:last-child{border-bottom:0}
.kv>span{color:var(--muted);font-size:.85em;flex:0 0 auto}
.kv>b{font-weight:600;text-align:right;word-break:break-word}
.kv .cost{color:var(--brand)}
.confirm-actions{display:flex;align-items:center;gap:14px;margin-top:22px}
.confirm-actions form{margin:0}
.btn-ghost{display:inline-block;padding:11px 18px;border-radius:var(--radius-sm);border:1px solid var(--line);color:var(--muted);cursor:pointer;transition:border-color .15s,color .15s}
.btn-ghost:hover{border-color:var(--red);color:var(--red)}
.credits-badge{display:inline-block;background:var(--panel-2);border:1px solid var(--line);border-radius:999px;padding:6px 14px;color:var(--muted);font-size:.85em;white-space:nowrap}
.credits-badge strong{color:var(--brand)}
@media (max-width:720px){.confirm-grid{grid-template-columns:1fr}}

/* Fields that belong together, in one box — not scattered across the grid, which is how a
   control ends up far from the value it changes and quietly gets missed. */
.subform{grid-column:1/-1;border:1px solid var(--line,#2a2f3a);border-radius:10px;
         padding:10px 14px 12px;margin:2px 0 0;background:rgba(255,255,255,.02)}
.subform legend{padding:0 6px;font-size:.78rem;letter-spacing:.05em;text-transform:uppercase;
                color:var(--muted,#8b93a7)}
/* Stretch, so a choice that carries a second line of detail does not end up a different
   height from the one beside it. */
.subform-row{display:flex;gap:12px;align-items:stretch;flex-wrap:wrap}
.subform-row label{flex:1 1 220px;margin:0}
.subform-row .ghost{flex:0 0 auto;height:38px;padding:0 16px;white-space:nowrap;
                    background:transparent;border:1px solid var(--line,#3a4150);
                    border-radius:8px;color:inherit;cursor:pointer;font:inherit}
.subform-row .ghost:hover,.subform-row .ghost:focus-visible{
                    border-color:var(--accent,#e8b73a);color:var(--accent,#e8b73a)}
.subform .hint{margin:10px 0 0;font-size:.82rem;line-height:1.5;color:var(--muted,#8b93a7)}

/* Recipient picking: the same table the rest of the portal uses, with a tick column. Filters
   above it, and the rows themselves drawn by the server and swapped in whole. */
.filters{display:flex;flex-wrap:wrap;gap:10px;margin-top:12px;align-items:flex-end}
.filter{display:flex;flex-direction:column;gap:5px;font-size:.78rem;letter-spacing:.05em;
        text-transform:uppercase;color:var(--muted,#8b93a7);margin:0}
.filter.grow{flex:1 1 240px;min-width:0}
.filter select,.filter input[type=search]{padding:9px 11px;font:inherit;text-transform:none;
        letter-spacing:normal;border-radius:8px;border:1px solid var(--line,#2a2f3a);
        background:rgba(255,255,255,.03);color:var(--text,#e6e9f0);min-width:170px}
.filter.grow input[type=search]{width:100%;min-width:0}

/* The recipient table is an ordinary portal table: it uses .table-wrap as it stands, so it
   turns into labelled cards on a narrow screen like every other table, and the page scrolls
   rather than a box inside it. */
.table-wrap.loading{opacity:.5}
.picktable .tick{width:38px;padding-right:0}
.picktable .tick input{margin:0;cursor:pointer}

.chosen-row{display:flex;align-items:center;gap:12px;margin-top:10px}
.chosen-count{font-size:.88rem;color:var(--muted,#8b93a7);font-variant-numeric:tabular-nums}
.chosen-count.some{color:var(--accent,#e8b73a)}

.picker{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:8px;
        margin-top:10px}
/* A choice between two things is one control, so it is drawn as one: a single bordered group
   split into segments, with the chosen segment lit. Two separate boxes drift apart the moment
   one of them carries a second line of detail. */
.seg{display:inline-flex;flex-wrap:wrap;margin:12px 0 0;padding:0;border:1px solid var(--line);
     border-radius:var(--radius-sm);overflow:hidden;background:var(--panel-2)}
.seg label{display:flex;flex-direction:row;align-items:center;gap:10px;margin:0;
           padding:11px 16px;cursor:pointer;color:var(--ink);font-size:.92rem;
           border-right:1px solid var(--line)}
.seg label:last-child{border-right:0}
.seg label:hover{background:rgba(255,255,255,.04)}
.seg label:has(input:checked){background:var(--brand-soft);color:var(--brand)}
.seg label span{display:flex;flex-direction:column;line-height:1.25}
.seg label span small{color:var(--muted);font-size:.76rem}
.seg label:has(input:checked) span small{color:inherit;opacity:.8}

/* A .pick is a <label>, and labels are laid out in a column everywhere else in the portal —
   without resetting that the button lands above its own text instead of beside it. */
.pick{display:flex;flex-direction:row;align-items:center;gap:9px;margin:0;padding:9px 12px;
      cursor:pointer;border:1px solid var(--line,#2a2f3a);border-radius:8px;
      background:rgba(255,255,255,.02)}
.pick:hover{border-color:var(--accent,#e8b73a)}
.pick input{margin:0;flex:0 0 auto}
.pick span{display:flex;flex-direction:column;line-height:1.25;min-width:0}
.pick span small{color:var(--muted,#8b93a7);font-size:.76rem}
.subform-row .pick{flex:0 0 auto}

.quote{margin:0;padding:12px 14px;border-left:3px solid var(--accent,#e8b73a);
       background:rgba(255,255,255,.03);border-radius:0 8px 8px 0;font-size:1.02rem}
.pill.ok{background:rgba(34,197,94,.16);color:#22c55e}
.pill.wait{background:rgba(232,183,58,.16);color:#e8b73a}
.right{text-align:right}
.nowrap{white-space:nowrap}
.btn.small{padding:4px 10px;font-size:.82rem}
textarea{width:100%;resize:vertical;font:inherit;padding:10px 12px;border-radius:8px;
         border:1px solid var(--line,#2a2f3a);background:rgba(255,255,255,.03);color:inherit}

.link-btn{background:none;border:0;padding:0;font:inherit;font-size:.8rem;cursor:pointer;
          color:var(--accent,#e8b73a);text-decoration:underline;text-underline-offset:3px}
.link-btn:hover{opacity:.8}
button.primary:disabled{opacity:.45;cursor:not-allowed}
