:root{
  --bg:#f3f6f8; --panel:#fff; --ink:#0f1b26; --muted:#5a6876; --line:#d8e0e7; --soft:#edf2f5;
  --accent:#0E7C9B; --accent-soft:#dff0f5; --ok:#15803d; --ok-soft:#e2f4e7; --fail:#c62828; --fail-soft:#fbe6e6;
  --warn:#a15c07; --warn-soft:#fdf0d9; --pink:#db2777;
  --mono:ui-monospace,"SFMono-Regular","Cascadia Mono",Menlo,Consolas,monospace;
  --sans:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --dev-fill:#ffffff; --dev-stroke:#33414e; --screen:#d9eef5; --canvas:#f8fafb; --grid:#e7edf1;
  color-scheme:light;
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:#0e141a; --panel:#151d25; --ink:#e4ebf1; --muted:#97a6b4; --line:#2a3642; --soft:#1b2530;
    --accent:#3fb3d3; --accent-soft:#16323d; --ok:#4ade80; --ok-soft:#14301f; --fail:#f87171; --fail-soft:#3a1b1d;
    --warn:#fbbf24; --warn-soft:#3a2c12; --pink:#f472b6;
    --dev-fill:#1d2731; --dev-stroke:#b9c6d2; --screen:#1f4250; --canvas:#111920; --grid:#1a242d; color-scheme:dark;
  }
}
:root[data-theme="dark"]{
  --bg:#0e141a; --panel:#151d25; --ink:#e4ebf1; --muted:#97a6b4; --line:#2a3642; --soft:#1b2530;
  --accent:#3fb3d3; --accent-soft:#16323d; --ok:#4ade80; --ok-soft:#14301f; --fail:#f87171; --fail-soft:#3a1b1d;
  --warn:#fbbf24; --warn-soft:#3a2c12; --pink:#f472b6;
  --dev-fill:#1d2731; --dev-stroke:#b9c6d2; --screen:#1f4250; --canvas:#111920; --grid:#1a242d; color-scheme:dark;
}
*{box-sizing:border-box}
[hidden]{display:none !important}
html{font-size:14px}
html.big{font-size:18px}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--sans);line-height:1.45}
a{color:var(--accent)}
code,.mono{font-family:var(--mono);font-size:.92em}
button,select,input,textarea{font:inherit;color:inherit}
.btn{border:1px solid var(--line);background:var(--panel);border-radius:7px;padding:.32rem .65rem;cursor:pointer;font-size:.86rem;white-space:nowrap;line-height:1.3}
.btn:hover{border-color:var(--accent);color:var(--accent)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}
.btn.primary:hover{filter:brightness(1.08);color:#fff}
.btn.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent);font-weight:600}
.btn.small{padding:.15rem .45rem;font-size:.78rem}
.btn.danger:hover{border-color:var(--fail);color:var(--fail)}
.btn:disabled{opacity:.45;cursor:default}
select,input[type=text],input[type=number]{border:1px solid var(--line);border-radius:6px;background:var(--panel);padding:.25rem .4rem;min-width:0}
input[type=text]:focus,input[type=number]:focus,select:focus{outline:2px solid var(--accent-soft);border-color:var(--accent)}
.lbl{font-size:.78rem;color:var(--muted)}

/* En-tête */
header.top{display:flex;align-items:center;gap:.8rem;flex-wrap:wrap;padding:.55rem 1rem;border-bottom:1px solid var(--line);background:var(--panel)}
header.top .crumbs{font-size:.8rem;color:var(--muted)}
header.top .crumbs a{text-decoration:none}
header.top h1{font-size:1.1rem;margin:0;font-weight:650}
.modes{display:flex;gap:2px;background:var(--soft);border-radius:9px;padding:3px;margin-left:auto}
.modes button{border:none;background:none;padding:.35rem .75rem;border-radius:7px;cursor:pointer;font-weight:600;color:var(--muted);font-size:.88rem}
.modes button[aria-pressed=true]{background:var(--panel);color:var(--accent);box-shadow:0 1px 2px rgba(0,0,0,.12)}
.top-actions{display:flex;gap:.35rem;flex-wrap:wrap}

/* Barre d'outils */
.toolbar{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap;padding:.45rem 1rem;border-bottom:1px solid var(--line);background:var(--panel)}
.toolbar .sep{width:1px;height:22px;background:var(--line);margin:0 .3rem}
.toolbar label{font-size:.82rem;color:var(--muted);display:inline-flex;align-items:center;gap:.3rem}
.clock{font-family:var(--mono);font-size:.8rem;color:var(--muted);min-width:7ch}
.state-pill{font-size:.75rem;font-weight:700;padding:.1rem .5rem;border-radius:20px;background:var(--soft);color:var(--muted)}
.state-pill.run{background:var(--ok-soft);color:var(--ok)}
.state-pill.wait{background:var(--warn-soft);color:var(--warn)}

/* Mise en page */
.lab{display:grid;grid-template-columns:minmax(0,1fr) 380px;grid-template-rows:minmax(420px,1fr) auto;gap:0;height:calc(100vh - 98px);min-height:640px}
.stage{position:relative;background:var(--canvas);border-right:1px solid var(--line);overflow:hidden;min-height:0}
#net{width:100%;height:100%;display:block;touch-action:none}
.side{grid-row:1 / span 2;grid-column:2;overflow:auto;background:var(--panel);padding:.9rem 1rem 2rem}
.bottom{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);border-top:1px solid var(--line);border-right:1px solid var(--line);background:var(--panel);height:220px;min-height:0}
.bottom h3{margin:0;font-size:.8rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);display:flex;align-items:center;gap:.5rem;padding:.45rem .7rem;border-bottom:1px solid var(--line)}
.logbox{display:flex;flex-direction:column;min-height:0;border-right:1px solid var(--line)}
#log{overflow:auto;padding:.3rem .7rem;font-size:.82rem;flex:1}
#log .e{padding:.18rem 0;border-bottom:1px dashed var(--line);display:grid;grid-template-columns:5.2ch 6.5em 1fr;gap:.4rem}
#log .e .t{font-family:var(--mono);color:var(--muted);font-size:.75rem}
#log .e .d{font-weight:650}
#log .e.k-err .x{color:var(--fail)}
#log .e.k-ok .x{color:var(--ok)}
#log .e.k-warn .x{color:var(--warn)}
#log .e.k-muted{color:var(--muted)}
#log .e.msg{background:var(--soft)}
.framebox{display:flex;flex-direction:column;min-height:0}
#frame{overflow:auto;padding:.5rem .7rem;font-size:.82rem}
.fr-row{display:flex;flex-wrap:wrap;gap:2px;margin:.25rem 0}
.fr-f{border:1px solid var(--line);border-radius:4px;padding:.15rem .4rem;background:var(--soft);cursor:help}
.fr-f b{display:block;font-size:.68rem;color:var(--muted);font-weight:600;text-transform:uppercase;letter-spacing:.03em}
.fr-f span{font-family:var(--mono);font-size:.8rem}
.fr-f.hd{background:var(--accent-soft)}
.fr-f.tag{background:var(--warn-soft)}
.fr-f.ip{background:var(--ok-soft)}

/* SVG */
#net text{font-family:var(--sans);fill:var(--ink)}
#net .dev{cursor:pointer}
#net .dev .body{fill:var(--dev-fill);stroke:var(--dev-stroke);stroke-width:1.6}
#net .dev .screen{fill:var(--screen);stroke:none}
#net .dev .stand{fill:var(--dev-stroke)}
#net .dev.sel .body{stroke:var(--accent);stroke-width:3}
#net .dev.off{opacity:.42}
#net .dev .name{font-size:13px;font-weight:650;text-anchor:middle}
#net .dev .ip{font-size:11px;text-anchor:middle;fill:var(--muted);font-family:var(--mono)}
#net .dev .lab{font-size:10px;text-anchor:middle;fill:var(--muted)}
#net .dev .pn{font-size:8.5px;text-anchor:middle;fill:var(--muted)}
#net .badge circle{stroke:var(--panel);stroke-width:1.5}
#net .badge text{font-size:9px;font-weight:800;fill:#fff;text-anchor:middle}
#net .port{stroke:var(--dev-stroke);stroke-width:1.2;cursor:crosshair}
#net .port.s-neutral{fill:var(--panel)}
#net .port.s-free{fill:#f59e0b}
#net .port.s-ok{fill:#22c55e}
#net .port.s-err{fill:#ef4444}
#net .port.s-blk{fill:var(--pink)}
#net .port.s-off{fill:#9ca3af}
#net .port.pick{stroke:var(--accent);stroke-width:3}
#net .cab .wire{stroke:var(--muted);stroke-width:2.6;fill:none}
#net .cab .wire.t-croise{stroke-dasharray:9 4}
#net .cab .wire.t-telecom{stroke-dasharray:2 4;stroke-width:3.4}
#net .cab .wire.err{stroke:var(--fail)}
#net .cab .hit{stroke:transparent;stroke-width:14;cursor:pointer}
#net .cab.sel .wire{stroke:var(--accent);stroke-width:4}
#net .cab .ct{font-size:10px;fill:var(--muted);text-anchor:middle}
#net .cell{stroke-linecap:butt;stroke-width:5;cursor:help}
#net .rubber{stroke:var(--accent);stroke-width:2;stroke-dasharray:5 4;pointer-events:none}
#net .flash{animation:flash 1s ease-out}
@keyframes flash{0%{opacity:1}100%{opacity:0}}

/* Bulles (mini-démos) */
.bubble{position:absolute;max-width:290px;background:var(--panel);border:1px solid var(--line);border-left:4px solid var(--accent);border-radius:8px;padding:.4rem .55rem;font-size:.8rem;box-shadow:0 6px 20px rgba(15,27,38,.16);transform:translate(-50%,-100%);pointer-events:none;z-index:6;line-height:1.35}
.bubble b{display:block;font-size:.72rem;color:var(--muted);text-transform:uppercase;letter-spacing:.04em}
.bubble.k-err{border-left-color:var(--fail)}
.bubble.k-ok{border-left-color:var(--ok)}
.bubble.k-warn{border-left-color:var(--warn)}
.bubble.k-muted{border-left-color:var(--line);color:var(--muted)}
.toasts{position:absolute;top:.6rem;right:.6rem;display:flex;flex-direction:column;gap:.35rem;z-index:8;max-width:360px}
.toast{background:var(--panel);border:1px solid var(--line);border-radius:8px;padding:.45rem .65rem;font-size:.84rem;box-shadow:0 6px 20px rgba(15,27,38,.15);border-left:4px solid var(--accent)}
.toast.ok{border-left-color:var(--ok)}
.toast.err{border-left-color:var(--fail)}
.toast.warn{border-left-color:var(--warn)}
.askbox{position:absolute;right:.7rem;bottom:2.6rem;z-index:9;width:min(430px,calc(100% - 1.4rem));background:var(--panel);border:2px solid var(--accent);border-radius:10px;padding:.7rem .8rem;box-shadow:0 10px 30px rgba(15,27,38,.25)}
.askbox h4{margin:0 0 .4rem;font-size:.92rem}
.askbox label{display:flex;gap:.45rem;align-items:flex-start;padding:.2rem 0;font-size:.86rem;cursor:pointer}
.askbox .tbl{font-family:var(--mono);font-size:.76rem;color:var(--muted);margin:.3rem 0}
.zoom{position:absolute;left:.6rem;top:.6rem;display:flex;gap:.25rem;z-index:5}
.hint-canvas{position:absolute;left:50%;bottom:.6rem;transform:translateX(-50%);font-size:.78rem;color:var(--muted);background:var(--panel);border:1px solid var(--line);border-radius:20px;padding:.2rem .7rem;z-index:4;white-space:nowrap}

/* Panneau latéral */
.side h2{font-size:1.05rem;margin:.1rem 0 .5rem;display:flex;align-items:center;gap:.4rem}
.side h3{font-size:.82rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin:1.1rem 0 .45rem;font-weight:700}
.side p{margin:.35rem 0}
.side .tagl{display:inline-block;font-size:.72rem;font-weight:700;border-radius:20px;padding:.08rem .55rem;background:var(--accent-soft);color:var(--accent)}
.side .lead{color:var(--ink)}
.side ul{padding-left:1.1rem;margin:.3rem 0}
.side li{margin:.2rem 0}
.side details{border:1px solid var(--line);border-radius:7px;padding:.35rem .55rem;margin:.35rem 0}
.side details summary{cursor:pointer;font-weight:600;font-size:.88rem}
.side details[open] summary{margin-bottom:.3rem}
.acts{display:flex;flex-direction:column;gap:.35rem}
.acts .btn{text-align:left;white-space:normal}
.acts .btn small{display:block;color:var(--muted);font-size:.75rem}
.fields{display:grid;grid-template-columns:auto 1fr;gap:.35rem .5rem;align-items:center;font-size:.86rem}
.fields input,.fields select{width:100%}
.fields input[type=checkbox]{width:auto;margin:0 .3rem 0 0}
.fields label{display:flex;align-items:center}
.row{display:flex;gap:.35rem;align-items:center;flex-wrap:wrap}
.row input[type=text]{flex:1;min-width:6em}
table.t{border-collapse:collapse;width:100%;font-size:.8rem}
table.t th{text-align:left;color:var(--muted);font-weight:600;border-bottom:1px solid var(--line);padding:.2rem .3rem}
table.t td{border-bottom:1px solid var(--line);padding:.22rem .3rem;font-family:var(--mono);font-size:.76rem;vertical-align:middle}
table.t td.n{font-family:var(--sans)}
table.t tr.auto td{color:var(--muted)}
table.t .x{border:none;background:none;color:var(--muted);cursor:pointer;padding:0 .2rem}
table.t .x:hover{color:var(--fail)}
.empty{color:var(--muted);font-size:.82rem;font-style:italic}
.form{background:var(--soft);border-radius:8px;padding:.5rem;margin:.4rem 0;display:flex;flex-direction:column;gap:.35rem}
.callout{border-radius:8px;padding:.5rem .65rem;font-size:.84rem;margin:.5rem 0;background:var(--accent-soft)}
.callout.err{background:var(--fail-soft)}
.callout.ok{background:var(--ok-soft)}
.callout.warn{background:var(--warn-soft)}
.kv{font-size:.82rem}
.kv div{display:flex;justify-content:space-between;gap:.5rem;border-bottom:1px dashed var(--line);padding:.15rem 0}
.kv span:last-child{font-family:var(--mono)}
.ttl-h{color:var(--ok)}.ttl-m{color:var(--warn)}.ttl-l{color:var(--fail)}

/* Exercices */
.exo-box{border:1px solid var(--accent);border-radius:10px;padding:.2rem .8rem .7rem;margin-top:1.1rem;background:var(--accent-soft)}
.exo-box h3{color:var(--accent)}
.exo-prog{height:6px;background:var(--soft);border-radius:4px;overflow:hidden;margin:.3rem 0 .5rem}
.exo-prog span{display:block;height:100%;background:var(--accent)}
.exo-q{font-size:.98rem;font-weight:600;margin:.6rem 0}
.exo-choices{display:flex;flex-direction:column;gap:.35rem}
.exo-choices label{display:flex;gap:.5rem;align-items:flex-start;border:1px solid var(--line);border-radius:8px;padding:.45rem .6rem;cursor:pointer;font-size:.9rem}
.exo-choices label:hover{border-color:var(--accent)}
.exo-choices label.good{border-color:var(--ok);background:var(--ok-soft)}
.exo-choices label.bad{border-color:var(--fail);background:var(--fail-soft)}
.exo-input{flex:1;font-size:1rem;padding:.4rem .5rem}
.exo-score{display:flex;align-items:baseline;gap:.8rem;border-radius:10px;padding:.7rem 1rem;margin:.5rem 0}
.exo-score b{font-size:2rem}
.exo-score.ok{background:var(--ok-soft);color:var(--ok)}
.exo-score.warn{background:var(--warn-soft);color:var(--warn)}
.exo-score.err{background:var(--fail-soft);color:var(--fail)}
.exo-recap{padding-left:1.2rem;font-size:.84rem}
.exo-recap li{margin:.3rem 0}
.exo-recap li.ok span{color:var(--ok);font-weight:700}
.exo-recap li.ko span{color:var(--fail);font-weight:700}
.exo-recap small{display:block;color:var(--muted)}
.card .done{font-size:.72rem;font-weight:700;border-radius:20px;padding:.05rem .45rem;background:var(--ok-soft);color:var(--ok)}
.card .done.part{background:var(--warn-soft);color:var(--warn)}

/* Catalogue */
.cat-wrap{max-width:1180px;margin:0 auto;padding:2rem 16px 3rem}
.cat-wrap .brand{font-size:.8rem;letter-spacing:.08em;text-transform:uppercase;color:var(--accent);font-weight:700}
.cat-wrap h1{font-size:1.9rem;margin:.2rem 0 .4rem;letter-spacing:-.02em}
.cat-wrap .lead{color:var(--muted);max-width:70ch;margin:0 0 1.2rem}
.cat-wrap h2{font-size:1.05rem;margin:2rem 0 .3rem}
.cat-wrap h2 + p{color:var(--muted);margin:0 0 .8rem;font-size:.92rem}
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,270px),1fr));gap:.8rem}
.card{display:flex;flex-direction:column;gap:.35rem;background:var(--panel);border:1px solid var(--line);border-radius:11px;padding:.9rem 1rem;text-decoration:none;color:inherit}
a.card:hover{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.card h3{margin:0;font-size:1rem}
.card p{margin:0;color:var(--muted);font-size:.88rem;flex:1}
.card .meta{display:flex;gap:.3rem;flex-wrap:wrap}
.card .meta span{font-size:.7rem;font-weight:700;border-radius:20px;padding:.05rem .45rem;background:var(--soft);color:var(--muted)}
.card .num{font-family:var(--mono);font-size:.75rem;color:var(--accent);font-weight:700}

@media (max-width:1000px){
  .hint-canvas{display:none}
  .lab{grid-template-columns:1fr;grid-template-rows:62vh auto auto;height:auto}
  .side{grid-row:auto;grid-column:auto;border-top:1px solid var(--line)}
  .bottom{grid-template-columns:1fr;height:auto}
  .logbox{border-right:none;max-height:260px}
  .modes{margin-left:0}
}

.bilan-link{display:flex;gap:.8rem;align-items:center;flex-wrap:wrap;margin:.2rem 0 1rem}
.bilan-link span{color:var(--muted);font-size:.9rem}
.bilan-link .btn{text-decoration:none}
.card .meta .done{background:var(--ok-soft);color:var(--ok)}
.card .meta .done.part{background:var(--warn-soft);color:var(--warn)}

/* ---- Mon bilan ---- */
.bilan-id{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,190px),1fr));gap:.6rem;background:var(--panel);border:1px solid var(--line);border-radius:11px;padding:.9rem 1rem}
.bilan-id label{display:flex;flex-direction:column;gap:.2rem;font-size:.8rem;color:var(--muted);font-weight:600}
.bilan-id input{font:inherit;font-size:.95rem;padding:.35rem .5rem;border:1px solid var(--line);border-radius:7px;background:var(--bg);color:var(--ink)}
.bilan-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,160px),1fr));gap:.6rem;margin:1rem 0}
.bilan-stats div{background:var(--panel);border:1px solid var(--line);border-radius:11px;padding:.7rem 1rem}
.bilan-stats b{display:block;font-size:1.5rem;letter-spacing:-.02em}
.bilan-stats span{color:var(--muted);font-size:.82rem}
.bilan-actions{display:flex;gap:.5rem;flex-wrap:wrap;margin:1rem 0}
.bilan-actions .btn{text-decoration:none}
.tbl-wrap{overflow-x:auto;background:var(--panel);border:1px solid var(--line);border-radius:11px}
.bilan-tbl{width:100%;border-collapse:collapse;font-size:.88rem}
.bilan-tbl th,.bilan-tbl td{padding:.45rem .7rem;border-bottom:1px solid var(--line);text-align:left;vertical-align:top}
.bilan-tbl th{font-size:.74rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted)}
.bilan-tbl tr.grp td{background:var(--soft);font-weight:700;font-size:.82rem}
.bilan-tbl tr:last-child td{border-bottom:0}
.bilan-tbl .todo{color:var(--muted)}
.score{font-weight:700;border-radius:20px;padding:.05rem .5rem;font-size:.8rem;white-space:nowrap}
.score.ok{background:var(--ok-soft);color:var(--ok)}
.score.warn{background:var(--warn-soft);color:var(--warn)}
.score.err{background:var(--fail-soft);color:var(--fail)}
.bilan-det details{margin:.3rem 0}
.bilan-det summary{cursor:pointer;color:var(--accent);font-size:.82rem}
.bilan-det ol{margin:.3rem 0 .5rem;padding-left:1.3rem;font-size:.82rem}
.bilan-det li{margin:.2rem 0}
.bilan-det .k{color:var(--ok);font-weight:700}.bilan-det .x{color:var(--fail);font-weight:700}
.bilan-det .ans{color:var(--muted)}
.print-only{display:none}
.bilan-note{color:var(--muted);font-size:.85rem;margin-top:1.2rem}
@media print{
  :root{--bg:#fff;--panel:#fff;--ink:#000;--muted:#444;--line:#bbb;--soft:#f0f0f0}
  body{background:#fff}
  .no-print{display:none !important}
  .print-only{display:block}
  .cat-wrap{padding:0;max-width:none}
  .bilan-id input{border:0;padding:0;font-weight:700;background:none}
  .tbl-wrap{overflow:visible;border:0}
  .bilan-tbl tr{break-inside:avoid}
  .bilan-det details{display:block}
  .bilan-det details:not([open]) > :not(summary){display:none}
  a{color:inherit;text-decoration:none}
}
