nio-cat 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,76 @@
1
+ <!doctype html>
2
+ <html lang="ca">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, interactive-widget=resizes-content">
6
+ <title>nio // Panell</title>
7
+ <meta name="description" content="Dona feina als agents d’IA del teu ordinador des del mòbil, segueix-los en directe i aprova cada pas.">
8
+ <meta name="robots" content="noindex">
9
+ <meta name="theme-color" content="#f0ede7">
10
+ <meta name="apple-mobile-web-app-capable" content="yes">
11
+ <meta name="mobile-web-app-capable" content="yes">
12
+ <meta name="apple-mobile-web-app-status-bar-style" content="default">
13
+ <meta name="apple-mobile-web-app-title" content="nio">
14
+ <meta property="og:type" content="website">
15
+ <meta property="og:site_name" content="nio">
16
+ <meta property="og:locale" content="ca_ES">
17
+ <meta property="og:url" content="https://www.nio.cat/app">
18
+ <meta property="og:title" content="nio // Panell">
19
+ <meta property="og:description" content="Dona feina als agents d’IA del teu ordinador des del mòbil, segueix-los en directe i aprova cada pas.">
20
+ <meta property="og:image" content="https://www.nio.cat/og.png">
21
+ <meta property="og:image:width" content="1200">
22
+ <meta property="og:image:height" content="630">
23
+ <meta property="og:image:alt" content="nio">
24
+ <meta name="twitter:card" content="summary_large_image">
25
+ <meta name="twitter:title" content="nio // Panell">
26
+ <meta name="twitter:description" content="Dona feina als agents d’IA del teu ordinador des del mòbil, segueix-los en directe i aprova cada pas.">
27
+ <meta name="twitter:image" content="https://www.nio.cat/og.png">
28
+ <link rel="manifest" href="/manifest.webmanifest">
29
+ <meta name="format-detection" content="telephone=no">
30
+ <link rel="icon" href="/favicon.svg" type="image/svg+xml">
31
+ <link rel="apple-touch-icon" href="/apple-touch-icon.png">
32
+ <link rel="preconnect" href="https://fonts.googleapis.com">
33
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
34
+ <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600&family=Caveat:wght@500;600&display=swap" rel="stylesheet">
35
+ <link rel="stylesheet" href="/bot.css">
36
+ <link rel="stylesheet" href="/board.css">
37
+ <link rel="stylesheet" href="/app/style.css">
38
+ </head>
39
+ <body>
40
+ <header class="mbar">
41
+ <button class="icon-btn burger" id="burger" type="button" aria-label="Obre el menú" aria-expanded="false" aria-controls="side"><span></span><span></span><span></span></button>
42
+ <a href="/" class="word" aria-label="nio">ni<span class="bot" data-mood="idle" aria-hidden="true"><span class="eyes"><i></i><i></i></span></span></a>
43
+ <span class="here" id="here"></span>
44
+ <span class="grow"></span>
45
+ <span id="mRight"></span>
46
+ </header>
47
+ <div class="scrim" id="scrim"></div>
48
+ <div class="shell">
49
+ <aside class="side" id="side">
50
+ <div class="brand"><a href="/" class="word" aria-label="nio">ni<span class="bot" data-mood="idle" aria-hidden="true"><span class="eyes"><i></i><i></i></span></span></a><button class="icon-btn collapse" id="collapse" type="button" aria-label="Plega el menú" aria-expanded="true"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><rect x="3.5" y="4.5" width="17" height="15" rx="2.5"/><path d="M9.5 4.5v15M15.5 10l-2 2 2 2"/></svg></button></div>
51
+ <nav id="nav" aria-label="Seccions"></nav>
52
+ <div class="foot">
53
+ <div class="conn" id="sideConn"></div>
54
+ <button class="kbd" data-act="tour" type="button" title="Tutorial"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M9.6 9.3a2.5 2.5 0 0 1 4.8.9c0 1.7-2.4 2.2-2.4 3.6M12 17.2v.1"/></svg><span class="l">Tutorial</span></button>
55
+ <button class="kbd" data-act="palette" type="button" title="Cerca o fes una acció (⌘K)"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg><span class="l">Cerca o fes una acció</span><kbd>⌘K</kbd></button>
56
+ </div>
57
+ </aside>
58
+ <main class="main" id="main"><div id="view"></div></main>
59
+ </div>
60
+
61
+ <dialog class="sheet" id="sheet"><div class="sheet-in" id="sheetIn"></div></dialog>
62
+ <dialog id="palette" aria-label="Ordres">
63
+ <input type="search" id="palQ" placeholder="Escriu una ordre…" autocomplete="off" aria-controls="palList">
64
+ <ul id="palList" role="listbox"></ul>
65
+ </dialog>
66
+ <div class="tour" id="tour" hidden>
67
+ <div class="tour-spot" id="tourSpot"></div>
68
+ <div class="tour-card" id="tourCard" role="dialog" aria-modal="false" aria-labelledby="tourT"></div>
69
+ </div>
70
+ <div class="toasts" id="toasts" aria-live="polite"></div>
71
+
72
+ <script src="/bot.js"></script>
73
+ <script src="/board.js"></script>
74
+ <script src="/app/app.js" type="module"></script>
75
+ </body>
76
+ </html>
@@ -0,0 +1,381 @@
1
+ /* nio · app */
2
+ :root {
3
+ --bg: #f0ede7;
4
+ --bg-2: #e6e1d8;
5
+ --panel: #f8f6f2;
6
+ --fg: #272224;
7
+ --fg-muted: #69615c;
8
+ --accent: #f46a3b;
9
+ --border: #cec7bd;
10
+ --white: #fffefd;
11
+ --moss: #5b6551;
12
+ --lemon: #e7e66a;
13
+ --red: #e2382b;
14
+ --blue: #2b5bd8;
15
+ --code: #ebe7df;
16
+ --font: "Manrope", system-ui, sans-serif;
17
+ --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
18
+ --radius: 12px;
19
+ --safe-t: env(safe-area-inset-top, 0px);
20
+ --safe-b: env(safe-area-inset-bottom, 0px);
21
+ --ease: cubic-bezier(.22, 1, .36, 1);
22
+ }
23
+ * { box-sizing: border-box; margin: 0; padding: 0; }
24
+ [hidden] { display: none !important; }
25
+ html { -webkit-text-size-adjust: 100%; }
26
+ body { background: var(--bg); color: var(--fg); font: 400 15px/1.5 var(--font); letter-spacing: -.015em; -webkit-font-smoothing: antialiased; overscroll-behavior-y: none; }
27
+ a { color: inherit; }
28
+ button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
29
+ button { cursor: pointer; }
30
+ ::selection { background: var(--lemon); }
31
+ :focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; border-radius: 6px; }
32
+ .muted { color: var(--fg-muted); }
33
+ .small { font-size: 13px; }
34
+ .mono { font-family: var(--mono); font-size: .9em; letter-spacing: 0; }
35
+ .ico { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; flex: none; }
36
+ .row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
37
+ .between { justify-content: space-between; }
38
+ .grow { flex: 1; min-width: 0; }
39
+ .stack { display: grid; gap: 10px; }
40
+ .stack-lg { display: grid; gap: 20px; }
41
+
42
+ /* ---------- Estructura ---------- */
43
+ * { -webkit-tap-highlight-color: transparent; }
44
+ .shell { transition: grid-template-columns .34s var(--ease); display: grid; grid-template-columns: 236px minmax(0, 1fr); min-height: 100vh; min-height: 100dvh; }
45
+ .side { overflow: hidden; white-space: nowrap; position: sticky; top: 0; height: 100vh; height: 100dvh; display: flex; flex-direction: column; gap: 24px; padding: 22px 14px; border-right: 1px solid var(--border); }
46
+ .brand { display: flex; align-items: baseline; justify-content: space-between; }
47
+ .brand .word { font-size: 26px; font-weight: 600; letter-spacing: -.07em; line-height: 1; text-decoration: none; }
48
+ .side nav { display: grid; gap: 2px; }
49
+ .side nav a { position: relative; overflow: hidden; display: flex; align-items: center; gap: 10px; padding: 9px 13px; border-radius: 10px; font-size: 14px; font-weight: 500; color: var(--fg-muted); text-decoration: none; transition: background-color .2s, color .2s; }
50
+ .side nav a .ico { width: 18px; height: 18px; }
51
+ .side nav a span.l { flex: 1 0 auto; }
52
+ .side nav a:hover { color: var(--fg); background: color-mix(in srgb, var(--bg-2) 60%, transparent); }
53
+ .side nav a[aria-current="page"] { color: var(--fg); background: var(--bg-2); }
54
+ .badge { min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px; background: var(--lemon); color: var(--fg); font-size: 11px; font-weight: 600; display: inline-grid; place-items: center; }
55
+ .side .foot { margin-top: auto; display: grid; gap: 8px; }
56
+ .conn { display: flex; align-items: center; gap: 8px; padding-left: 18px; overflow: hidden; font-size: 13px; color: var(--fg-muted); min-width: 0; }
57
+ .conn span { flex: none; white-space: nowrap; }
58
+ .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--border); flex: none; }
59
+ .dot.on { background: var(--moss); box-shadow: 0 0 0 3px color-mix(in srgb, var(--moss) 18%, transparent); }
60
+ .dot.wait { background: var(--accent); }
61
+ .kbd { display: flex; gap: 10px; align-items: center; overflow: hidden; width: 100%; padding: 9px 13px; border: 0; border-radius: 10px; background: none; color: var(--fg-muted); font-size: 14px; font-weight: 500; text-align: left; cursor: pointer; transition: background-color .2s, color .2s; }
62
+ .kbd:hover { color: var(--fg); background: color-mix(in srgb, var(--bg-2) 60%, transparent); }
63
+ .kbd .ico { width: 18px; height: 18px; }
64
+ .kbd kbd { border: 0; background: none; padding: 0; font: 500 12px var(--font); letter-spacing: .02em; color: var(--fg-muted); opacity: .7; }
65
+ .kbd .l { flex: 1 0 auto; white-space: nowrap; }
66
+ kbd { font: 600 11px var(--font); padding: 1px 6px; border: 1px solid var(--border); border-radius: 6px; background: var(--white); color: var(--fg-muted); }
67
+ .main { min-width: 0; display: flex; flex-direction: column; }
68
+ .page { padding: 32px 40px 96px; max-width: 1080px; width: 100%; }
69
+ .top { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 24px; }
70
+ .top h1 { font-size: 30px; font-weight: 500; letter-spacing: -.05em; line-height: 1.1; }
71
+ .top p { margin-top: 4px; color: var(--fg-muted); }
72
+ .mbar, .scrim { display: none; }
73
+
74
+ /* Menú plegable (escriptori): només es mou l'amplada de la barra. El contingut no s'anima: la vora el talla i el botó viatja amb ella. */
75
+ .main { min-width: 0; }
76
+ .brand { position: relative; align-items: center; height: 34px; padding: 0; }
77
+ .brand .word { margin-left: 13px; }
78
+ .brand .collapse { position: absolute; left: 0; top: 0; width: 34px; height: 34px; color: var(--fg-muted); transform: translateX(163px); transition: transform .34s var(--ease), color .2s; }
79
+ .brand .collapse svg { transition: transform .34s var(--ease); }
80
+ .brand .collapse:hover { color: var(--fg); }
81
+ @media (min-width: 821px) {
82
+ body.side-collapsed .shell { grid-template-columns: 72px minmax(0, 1fr); }
83
+ body.side-collapsed .brand .collapse { transform: translateX(4px); }
84
+ body.side-collapsed .brand .collapse svg { transform: scaleX(-1); }
85
+ body.side-collapsed .brand .word, body.side-collapsed .side nav .grp { visibility: hidden; }
86
+ body.side-collapsed .side nav a .badge { position: absolute; top: 2px; right: 2px; min-width: 16px; height: 16px; font-size: 9px; padding: 0 4px; }
87
+ }
88
+
89
+ /* ---------- Controls ---------- */
90
+ .btn { text-decoration: none; display: inline-flex; align-items: center; justify-content: center; gap: 7px; height: 38px; padding: 0 15px; border: 1px solid var(--border); border-radius: 10px; background: var(--white); font-size: 14px; font-weight: 600; white-space: nowrap; transition: background-color .2s, border-color .2s, transform .12s; }
91
+ .btn:hover { border-color: var(--fg); }
92
+ .btn:active { transform: scale(.98); }
93
+ .btn .ico { width: 17px; height: 17px; }
94
+ .btn.ink { background: var(--fg); color: var(--bg); border-color: var(--fg); }
95
+ .btn.ink:hover { background: color-mix(in srgb, var(--fg) 86%, var(--bg)); }
96
+ .btn.ok { background: var(--moss); color: var(--white); border-color: var(--moss); }
97
+ .btn.danger { color: var(--red); }
98
+ .btn.danger:hover { border-color: var(--red); }
99
+ .btn.ghost { background: transparent; border-color: transparent; }
100
+ .btn.ghost:hover { border-color: var(--border); }
101
+ .btn.sm { height: 30px; padding: 0 10px; font-size: 12px; }
102
+ .btn.block { width: 100%; }
103
+ .btn:disabled { opacity: .45; cursor: not-allowed; }
104
+ .icon-btn { position: relative; display: grid; place-items: center; width: 40px; height: 40px; border: 0; border-radius: 12px; background: none; color: var(--fg); }
105
+ .icon-btn:hover { background: color-mix(in srgb, var(--bg-2) 80%, transparent); }
106
+ .icon-btn .badge { position: absolute; top: 3px; right: 1px; min-width: 18px; height: 18px; font-size: 10px; }
107
+ input[type="text"], input[type="url"], input[type="search"], select, textarea.field { width: 100%; min-width: 0; height: 42px; padding: 0 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--white); outline: none; }
108
+ textarea.field { height: auto; padding: 10px 12px; resize: vertical; line-height: 1.45; }
109
+ input:focus, select:focus, textarea:focus { border-color: var(--fg); }
110
+ select { appearance: none; -webkit-appearance: none; padding-right: 40px; cursor: pointer; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2369615c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; background-size: 16px 16px; }
111
+ label.f { display: grid; gap: 6px; font-size: 13px; color: var(--fg-muted); align-content: start; }
112
+ .seg { display: flex; padding: 3px; border-radius: 11px; background: var(--bg-2); }
113
+ .seg button { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 34px; border: 0; border-radius: 8px; background: none; font-size: 13px; font-weight: 600; color: var(--fg-muted); white-space: nowrap; }
114
+ .seg button[aria-pressed="true"] { background: var(--white); color: var(--fg); }
115
+
116
+ .panel { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius); }
117
+ .panel > header { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 16px 18px; }
118
+ .panel > header h2 { font-size: 15px; font-weight: 600; letter-spacing: -.02em; }
119
+ .panel .body { padding: 0 18px 18px; }
120
+ .card { display: block; width: 100%; text-align: left; padding: 16px 18px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--panel); transition: border-color .2s, transform .12s; }
121
+ button.card:hover, a.card:hover { border-color: var(--fg); }
122
+ button.card:active { transform: scale(.995); }
123
+ .list { display: grid; gap: 10px; }
124
+ .card.row { display: flex; }
125
+ .sheet-foot { position: sticky; bottom: -24px; margin: 0 -24px -24px; padding: 14px 24px 24px; background: linear-gradient(to bottom, transparent, var(--bg) 30%); }
126
+ .section-title { font-size: 12px; font-weight: 600; color: var(--fg-muted); margin: 22px 0 8px; }
127
+ .chip { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px; border-radius: 999px; border: 1px solid var(--border); background: var(--white); font-size: 12px; font-weight: 600; white-space: nowrap; color: var(--fg); }
128
+ button.chip:hover { border-color: var(--fg); }
129
+ .chip.running { background: var(--fg); color: var(--bg); border-color: var(--fg); }
130
+ .chip.waiting { background: var(--lemon); border-color: var(--lemon); }
131
+ .chip.error { color: var(--red); border-color: color-mix(in srgb, var(--red) 40%, transparent); }
132
+ .chip.beta { height: 20px; padding: 0 7px; font-size: 10px; color: var(--fg-muted); }
133
+ .pulse { width: 6px; height: 6px; border-radius: 50%; background: currentColor; animation: pulse 1.2s ease-in-out infinite; }
134
+ @keyframes pulse { 50% { opacity: .3; } }
135
+ .agent-tag { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 600; }
136
+ .agent-tag::before { content: ""; width: 8px; height: 8px; border-radius: 3px; background: var(--c, var(--fg-muted)); }
137
+ [data-agent="claude"] { --c: var(--accent); } [data-agent="codex"] { --c: var(--moss); } [data-agent="grok"] { --c: var(--fg); }
138
+ [data-agent="antigravity"] { --c: var(--blue); } [data-agent="ollama"] { --c: #b08a5a; } [data-agent="demo"] { --c: var(--lemon); } [data-agent="browser"] { --c: #8a5cf6; }
139
+ .empty { padding: 48px 20px; text-align: center; color: var(--fg-muted); display: grid; justify-items: center; gap: 8px; }
140
+ .empty .bot { --s: 56px; --bw: .13; color: var(--fg); margin-bottom: 8px; }
141
+ .empty h2 { font-size: 20px; font-weight: 500; letter-spacing: -.04em; color: var(--fg); }
142
+ .empty p { max-width: 42ch; }
143
+ .kv { display: grid; grid-template-columns: auto 1fr; gap: 6px 16px; font-size: 14px; }
144
+ .kv dt { color: var(--fg-muted); }
145
+ .kv dd { overflow-wrap: anywhere; }
146
+
147
+ /* ---------- Connecta ---------- */
148
+ .connect { display: grid; gap: 24px; min-width: 0; }
149
+ .connect-head h1 { font-size: clamp(30px, 4vw, 40px); font-weight: 500; letter-spacing: -.05em; line-height: 1.08; }
150
+ .connect-head .lead { color: var(--fg-muted); font-size: 16px; max-width: 58ch; margin-top: 10px; }
151
+ .connect-grid { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(260px, 1fr); gap: 16px; align-items: start; }
152
+ .conn-main { padding: 22px; display: grid; gap: 16px; min-width: 0; }
153
+ .stepper { list-style: none; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
154
+ .stepper li { display: flex; gap: 10px; align-items: flex-start; }
155
+ .stepper .n { flex: none; width: 26px; height: 26px; border-radius: 50%; background: var(--fg); color: var(--bg); display: grid; place-items: center; font-size: 12px; font-weight: 600; }
156
+ .stepper b { display: block; font-weight: 600; font-size: 14px; }
157
+ .stepper p { font-size: 13px; color: var(--fg-muted); margin-top: 2px; line-height: 1.4; }
158
+ .cmd { display: flex; align-items: center; gap: 8px; padding: 6px 6px 6px 14px; border-radius: 12px; background: var(--code); font-family: var(--mono); font-size: 14px; min-width: 0; }
159
+ .cmd code { flex: 1; min-width: 0; overflow-wrap: anywhere; line-height: 1.4; padding: 6px 0; }
160
+ .cmd .btn { flex: none; font-family: var(--font); }
161
+ .cmd.big { font-size: 16px; padding: 8px 8px 8px 18px; }
162
+ .reqs { display: flex; gap: 6px; flex-wrap: wrap; }
163
+ .chip.ghost { background: transparent; color: var(--fg-muted); }
164
+ .paste { border-top: 1px solid var(--border); padding-top: 12px; }
165
+ .paste summary { cursor: pointer; font-size: 14px; font-weight: 600; list-style: none; display: flex; justify-content: space-between; align-items: center; }
166
+ .paste summary::-webkit-details-marker { display: none; }
167
+ .paste summary::after { content: "+"; font-size: 18px; font-weight: 400; color: var(--fg-muted); }
168
+ .paste[open] summary::after { content: "−"; }
169
+ .paste .pair-form { display: flex; gap: 8px; margin: 12px 0 6px; }
170
+ .try { padding: 22px; display: grid; gap: 12px; justify-items: start; }
171
+ .try .bot { --s: 44px; --bw: .13; }
172
+ .try h2 { font-size: 18px; font-weight: 600; letter-spacing: -.03em; }
173
+ .side nav .grp { display: block; padding: 14px 13px 4px; font-size: 11px; font-weight: 600; color: var(--fg-muted); letter-spacing: .02em; }
174
+ .side nav .grp:first-child { padding-top: 0; }
175
+
176
+ /* ---------- Sessions ---------- */
177
+ .session-card .title { font-size: 16px; font-weight: 500; letter-spacing: -.02em; margin-top: 8px; }
178
+ .session-card .last { color: var(--fg-muted); font-size: 14px; margin-top: 4px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
179
+ .session-card .meta { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; font-size: 12px; color: var(--fg-muted); }
180
+ .fab { position: fixed; right: 24px; bottom: calc(24px + var(--safe-b)); z-index: 15; display: inline-flex; align-items: center; gap: 8px; height: 50px; padding: 0 20px 0 16px; border: 0; border-radius: 16px; background: var(--fg); color: var(--bg); font-weight: 600; box-shadow: 0 14px 30px -14px color-mix(in srgb, var(--fg) 70%, transparent); transition: transform .15s; }
181
+ .fab:active { transform: scale(.97); }
182
+
183
+ /* ---------- Xat de sessió ---------- */
184
+ .chat { display: flex; flex-direction: column; height: 100vh; height: 100dvh; }
185
+ .chat-head { display: flex; align-items: center; gap: 12px; padding: 14px 24px; border-bottom: 1px solid var(--border); }
186
+ .chat-head .bot { --s: 30px; --bw: .14; }
187
+ .chat-head h1 { font-size: 17px; font-weight: 600; letter-spacing: -.03em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
188
+ .chat-head .sub { font-size: 12px; color: var(--fg-muted); }
189
+ .mode-bar { display: flex; gap: 6px; padding: 10px 24px; overflow-x: auto; scrollbar-width: none; border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent); }
190
+ .mode-bar::-webkit-scrollbar { display: none; }
191
+ .feed { flex: 1; overflow-y: auto; padding: 22px 24px 30px; display: flex; flex-direction: column; gap: 12px; overscroll-behavior: contain; }
192
+ .feed > * { max-width: 760px; width: 100%; margin-left: auto; margin-right: auto; }
193
+ .msg-user { align-self: flex-end; width: auto !important; max-width: min(85%, 620px) !important; margin-right: max(0px, calc((100% - 760px) / 2)) !important; padding: 10px 14px; border-radius: 16px 16px 4px 16px; background: var(--fg); color: var(--bg); white-space: pre-wrap; overflow-wrap: anywhere; animation: rise .25s var(--ease); }
194
+ .msg-ai { line-height: 1.6; overflow-wrap: anywhere; animation: rise .25s var(--ease); }
195
+ .msg-ai p + p, .msg-ai ul, .msg-ai ol, .msg-ai pre, .msg-ai h3 { margin-top: .6em; }
196
+ .msg-ai ul, .msg-ai ol { padding-left: 1.3em; }
197
+ .msg-ai h3 { font-size: 16px; font-weight: 600; }
198
+ .msg-ai code { font-family: var(--mono); font-size: .88em; padding: 1px 5px; border-radius: 6px; background: var(--code); }
199
+ .msg-ai pre { padding: 12px 14px; border-radius: 10px; background: var(--code); overflow-x: auto; }
200
+ .msg-ai pre code { padding: 0; background: none; font-size: 13px; }
201
+ .msg-ai a { text-underline-offset: 3px; text-decoration-color: var(--accent); }
202
+ .msg-ai.cursor > :last-child::after, .msg-ai.cursor:empty::after { content: ""; display: inline-block; width: 7px; height: 1.05em; margin-left: 2px; vertical-align: -.15em; background: var(--accent); animation: pulse 1s steps(1) infinite; }
203
+ .tool { border: 1px solid var(--border); border-radius: 10px; background: var(--panel); font-size: 13px; }
204
+ .tool summary { display: flex; align-items: center; gap: 10px; padding: 9px 12px; cursor: pointer; list-style: none; }
205
+ .tool summary::-webkit-details-marker { display: none; }
206
+ .tool .name { font-weight: 600; flex: none; }
207
+ .tool .arg { flex: 1; min-width: 0; font-family: var(--mono); font-size: 12px; color: var(--fg-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
208
+ .tool .st { flex: none; font-size: 12px; font-weight: 700; color: var(--fg-muted); }
209
+ .tool .st.ok { color: var(--moss); } .tool .st.err { color: var(--red); }
210
+ .tool pre { margin: 0 12px 12px; padding: 10px 12px; max-height: 320px; overflow: auto; border-radius: 8px; background: var(--code); font: 12px/1.5 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; }
211
+ .ev-info, .ev-result { text-align: center; font-size: 12px; color: var(--fg-muted); }
212
+ .ev-result { display: flex; justify-content: center; gap: 6px; }
213
+ .ev-error { padding: 10px 14px; border-radius: 10px; border: 1px solid color-mix(in srgb, var(--red) 35%, transparent); background: color-mix(in srgb, var(--red) 6%, var(--white)); color: var(--red); font-size: 14px; white-space: pre-wrap; }
214
+ .ev-logs { font-size: 12px; color: var(--fg-muted); }
215
+ .ev-logs summary { cursor: pointer; }
216
+ .ev-logs pre { margin-top: 6px; padding: 10px; border-radius: 8px; background: var(--code); font: 11px/1.5 var(--mono); max-height: 220px; overflow: auto; white-space: pre-wrap; }
217
+ .typing { display: flex; align-items: center; gap: 10px; color: var(--fg-muted); font-size: 13px; }
218
+ .typing .bot { --s: 22px; --bw: .15; color: var(--fg); }
219
+ @keyframes rise { from { opacity: 0; transform: translateY(6px); } }
220
+
221
+ .approval { padding: 16px; border-radius: var(--radius); border: 1.5px solid var(--accent); background: var(--white); display: grid; gap: 10px; animation: rise .25s var(--ease); }
222
+ .approval.done { border-color: var(--border); background: var(--panel); }
223
+ .approval .q { font-weight: 600; }
224
+ .approval pre { padding: 10px 12px; border-radius: 8px; background: var(--code); font: 12px/1.5 var(--mono); max-height: 260px; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; }
225
+ .approval .actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
226
+ .approval .actions .btn { height: 44px; font-size: 15px; }
227
+ .verdict { font-size: 13px; font-weight: 600; }
228
+ #feed .approval.done { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 10px; border: 1px solid var(--border); background: var(--panel); font-size: 13px; animation: none; }
229
+ #feed .approval.done .verdict { flex: none; padding: 2px 8px; border-radius: 999px; background: color-mix(in srgb, currentColor 10%, transparent); }
230
+ #feed .approval.done .what { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
231
+ #feed .approval.done .what .mono { color: var(--fg-muted); font-size: 12px; }
232
+ .approval.leaving { transition: opacity .4s .7s, transform .4s .7s; opacity: 0; transform: translateY(-4px); }
233
+ .verdict.allowed { color: var(--moss); } .verdict.denied { color: var(--red); }
234
+
235
+ .composer { display: flex; gap: 8px; align-items: flex-end; padding: 12px 24px calc(14px + var(--safe-b)); border-top: 1px solid var(--border); background: var(--bg); }
236
+ .composer > * { max-width: 760px; }
237
+ .composer .inner { flex: 1; display: flex; gap: 8px; align-items: flex-end; max-width: 760px; margin: 0 auto; width: 100%; }
238
+ .composer textarea { flex: 1; min-height: 46px; max-height: 180px; padding: 12px 14px; border: 1px solid var(--border); border-radius: 14px; background: var(--white); resize: none; outline: none; line-height: 1.4; }
239
+ .composer textarea:focus { border-color: var(--fg); }
240
+ .send { display: grid; place-items: center; width: 46px; height: 46px; flex: none; border: 0; border-radius: 14px; background: var(--fg); color: var(--bg); transition: transform .12s, background-color .2s; }
241
+ .send:active { transform: scale(.95); }
242
+ .send.stop { background: var(--red); }
243
+
244
+ /* ---------- Full (nova sessió, opcions) ---------- */
245
+ dialog.sheet { border: 0; padding: 0; margin: auto; width: min(560px, 100% - 32px); max-height: min(86vh, 860px); border-radius: 18px; background: var(--bg); color: var(--fg); overflow: auto; }
246
+ dialog.sheet::backdrop { background: color-mix(in srgb, var(--fg) 40%, transparent); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
247
+ dialog.sheet[open] { animation: pop .22s var(--ease); }
248
+ @keyframes pop { from { opacity: 0; transform: translateY(10px) scale(.98); } }
249
+ .sheet-in { padding: 24px; display: grid; gap: 18px; }
250
+ .sheet-in h2 { font-size: 22px; font-weight: 500; letter-spacing: -.045em; }
251
+ .sheet-in .grab { display: none; }
252
+ .picker { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
253
+ .pick { display: grid; gap: 2px; padding: 12px; border: 1px solid var(--border); border-radius: 12px; background: var(--white); text-align: left; }
254
+ .pick .sub { font-size: 12px; color: var(--fg-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
255
+ .pick[aria-pressed="true"] { border-color: var(--fg); box-shadow: inset 0 0 0 1px var(--fg); }
256
+ .pick.off { opacity: .5; }
257
+ .proj-list { display: grid; gap: 6px; max-height: 220px; overflow-y: auto; }
258
+ .proj { display: flex; gap: 10px; align-items: center; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--white); text-align: left; }
259
+ .proj .p { font: 11px var(--mono); color: var(--fg-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
260
+ .proj[aria-pressed="true"] { border-color: var(--fg); box-shadow: inset 0 0 0 1px var(--fg); }
261
+ .proj .ic { flex: none; width: 26px; height: 26px; border-radius: 8px; display: grid; place-items: center; background: var(--bg-2); font-size: 11px; font-weight: 700; }
262
+
263
+ /* ---------- Al mòbil ---------- */
264
+ .progress { height: 6px; border-radius: 999px; background: var(--bg-2); overflow: hidden; }
265
+ .progress i { display: block; height: 100%; background: var(--fg); border-radius: inherit; transition: width .2s; }
266
+ .model-card[aria-pressed="true"] { border-color: var(--fg); box-shadow: inset 0 0 0 1px var(--fg); }
267
+
268
+ /* ---------- Màquina ---------- */
269
+ .agent-row { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-top: 1px solid color-mix(in srgb, var(--border) 70%, transparent); }
270
+ .agent-row:first-child { border-top: 0; }
271
+ .grid2 { display: grid; grid-template-columns: 1.2fr 1fr; gap: 16px; align-items: start; }
272
+
273
+ /* ---------- Avisos, paleta, tutorial ---------- */
274
+ .toasts { position: fixed; right: 20px; bottom: calc(20px + var(--safe-b)); display: grid; gap: 8px; z-index: 60; }
275
+ .toast { max-width: 380px; padding: 12px 16px; border-radius: 12px; background: var(--fg); color: var(--bg); font-size: 14px; animation: rise .25s var(--ease); }
276
+ #palette { border: 0; padding: 0; width: min(560px, 100% - 32px); margin: 12vh auto auto; border-radius: 16px; background: var(--bg); color: var(--fg); }
277
+ #palette::backdrop { background: color-mix(in srgb, var(--fg) 40%, transparent); }
278
+ #palette input { height: 52px; border: 0; border-bottom: 1px solid var(--border); border-radius: 16px 16px 0 0; padding: 0 18px; font-size: 16px; }
279
+ #palette ul { list-style: none; max-height: 340px; overflow: auto; padding: 6px; }
280
+ #palette li { display: flex; justify-content: space-between; gap: 12px; padding: 10px 12px; border-radius: 10px; cursor: pointer; font-size: 14px; }
281
+ #palette li[aria-selected="true"] { background: var(--bg-2); }
282
+ #palette li span { color: var(--fg-muted); font-size: 12px; }
283
+
284
+ .tour { position: fixed; inset: 0; z-index: 40; pointer-events: none; }
285
+ .tour-spot { position: fixed; border-radius: 12px; box-shadow: 0 0 0 9999px color-mix(in srgb, var(--fg) 42%, transparent), 0 0 0 2px var(--white) inset; transition: left .35s var(--ease), top .35s var(--ease), width .35s var(--ease), height .35s var(--ease); }
286
+ .tour-card { position: fixed; width: 340px; pointer-events: auto; background: var(--bg); border-radius: 16px; padding: 18px; display: grid; gap: 10px; transition: left .35s var(--ease), top .35s var(--ease); }
287
+ .tour-card.center { width: min(420px, calc(100% - 32px)); padding: 28px; gap: 14px; text-align: center; justify-items: center; }
288
+ .tour-head { display: flex; align-items: center; gap: 12px; width: 100%; }
289
+ .tour-head .bot { --s: 34px; --bw: .13; }
290
+ .tour-card.center .tour-head { flex-direction: column; }
291
+ .tour-card.center .tour-head .bot { --s: 72px; }
292
+ .tour-step { font-size: 12px; color: var(--fg-muted); }
293
+ .tour-x { margin-left: auto; width: 28px; height: 28px; border: 0; border-radius: 8px; background: none; font-size: 18px; line-height: 1; color: var(--fg-muted); }
294
+ .tour-card.center .tour-x { position: absolute; top: 12px; right: 12px; }
295
+ .tour-card h3 { font-size: 19px; font-weight: 500; letter-spacing: -.035em; line-height: 1.2; }
296
+ .tour-card.center h3 { font-size: 26px; letter-spacing: -.045em; }
297
+ .tour-card p { font-size: 14px; color: var(--fg-muted); }
298
+ .tour-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; padding-top: 4px; }
299
+ .tour-card.center .tour-foot { justify-content: center; }
300
+
301
+ /* ---------- Pissarra ---------- */
302
+ body.board-mode .page { padding: 0; max-width: none; }
303
+ body.board-mode { overflow: hidden; overscroll-behavior: none; }
304
+ body.board-mode .view-enter { animation: none; }
305
+
306
+ @media (prefers-reduced-motion: no-preference) {
307
+ .view-enter { animation: view-in .25s var(--ease); }
308
+ @keyframes view-in { from { opacity: 0; transform: translateY(10px); } }
309
+ }
310
+ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }
311
+
312
+ @media (max-width: 1000px) { .grid2, .connect-grid { grid-template-columns: minmax(0, 1fr); } }
313
+ @media (max-width: 820px) {
314
+ .shell { grid-template-columns: minmax(0, 1fr); }
315
+ body.side-collapsed .shell { grid-template-columns: minmax(0, 1fr); }
316
+ .brand .collapse { display: none; }
317
+ .mbar { position: sticky; top: 0; z-index: 30; display: flex; align-items: center; gap: 6px; min-height: calc(56px + var(--safe-t)); padding: var(--safe-t) 8px 0; background: color-mix(in srgb, var(--bg) 72%, transparent); -webkit-backdrop-filter: blur(18px) saturate(160%); backdrop-filter: blur(18px) saturate(160%); border-bottom: 1px solid color-mix(in srgb, var(--border) 65%, transparent); }
318
+ .mbar .word { font-size: 24px; font-weight: 600; letter-spacing: -.07em; line-height: 1; text-decoration: none; padding-left: 4px; }
319
+ .mbar .here { font-size: 14px; color: var(--fg-muted); padding-left: 10px; margin-left: 2px; border-left: 1px solid var(--border); line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
320
+ .burger span { position: absolute; left: 11px; width: 18px; height: 2px; border-radius: 2px; background: currentColor; transition: transform .4s var(--ease), opacity .2s; }
321
+ .burger span:nth-child(1) { transform: translateY(-5px); } .burger span:nth-child(3) { transform: translateY(5px); }
322
+ body.nav-open .burger span:nth-child(1) { transform: rotate(45deg); }
323
+ body.nav-open .burger span:nth-child(2) { opacity: 0; }
324
+ body.nav-open .burger span:nth-child(3) { transform: rotate(-45deg); }
325
+ .side { position: fixed; z-index: 50; top: 0; left: 0; bottom: 0; width: min(304px, 86vw); padding: calc(20px + var(--safe-t)) 14px calc(20px + var(--safe-b)); overflow-y: auto; overscroll-behavior: contain; border-right: 1px solid color-mix(in srgb, var(--border) 60%, transparent); background: color-mix(in srgb, var(--bg) 70%, transparent); -webkit-backdrop-filter: blur(20px) saturate(160%); backdrop-filter: blur(20px) saturate(160%); transform: translateX(-104%); transition: transform .3s var(--ease), box-shadow .3s; will-change: transform; }
326
+ body.nav-open .side { transform: none; box-shadow: 24px 0 60px -30px color-mix(in srgb, var(--fg) 45%, transparent); }
327
+ .side.dragging { transition: none; }
328
+ .side nav a { padding: 12px; font-size: 16px; }
329
+ .side .foot .kbd kbd { display: none; }
330
+ .scrim { display: block; position: fixed; inset: 0; z-index: 45; background: color-mix(in srgb, var(--fg) 30%, transparent); opacity: 0; pointer-events: none; transition: opacity .3s ease-out; }
331
+ body.nav-open .scrim { opacity: 1; pointer-events: auto; }
332
+ body.nav-open { overflow: hidden; }
333
+ .page { padding: 20px 16px calc(100px + var(--safe-b)); }
334
+ .stepper { grid-template-columns: minmax(0, 1fr); }
335
+ .conn-main, .try { padding: 18px; }
336
+ .cmd.big { flex-direction: column; align-items: stretch; gap: 8px; padding: 12px; font-size: 13.5px; }
337
+ .cmd.big code { white-space: nowrap; overflow-x: auto; padding: 4px 2px; }
338
+ .cmd.big .btn { height: 38px; }
339
+ .paste .pair-form { flex-direction: column; }
340
+ .side nav .grp { padding: 16px 12px 4px; }
341
+ .top h1 { font-size: 26px; }
342
+ .chat { height: calc(100dvh - 56px - var(--safe-t)); }
343
+ body.chat-mode { overflow: hidden; }
344
+ body.chat-mode .shell { min-height: 0; }
345
+ body.chat-mode .mbar { position: fixed; left: 0; right: 0; transform: translateY(var(--vvt, 0px)); }
346
+ body.chat-mode .chat { position: fixed; left: 0; right: 0; top: calc(56px + var(--safe-t) + var(--vvt, 0px)); height: calc(var(--vvh, 100dvh) - 56px - var(--safe-t)); }
347
+ body.chat-mode.kb .composer { padding-bottom: 10px; }
348
+ .composer textarea, input[type="text"], input[type="url"], input[type="search"], select, textarea.field { font-size: 16px; }
349
+ .chat-head { display: none; }
350
+ .mode-bar { padding: 10px 16px; }
351
+ .feed { padding: 18px 16px 24px; }
352
+ .composer { padding: 10px 12px calc(10px + var(--safe-b)); }
353
+ .fab { right: 16px; bottom: calc(16px + var(--safe-b)); }
354
+ dialog.sheet { width: 100%; max-width: none; max-height: 92dvh; margin: auto 0 0; border-radius: 20px 20px 0 0; }
355
+ dialog.sheet[open] { animation: sheet-up .3s var(--ease); }
356
+ @keyframes sheet-up { from { transform: translateY(100%); } }
357
+ .sheet-in { padding: 10px 18px calc(22px + var(--safe-b)); }
358
+ .sheet-foot { bottom: calc(-22px - var(--safe-b)); margin: 0 -18px calc(-22px - var(--safe-b)); padding: 14px 18px calc(22px + var(--safe-b)); }
359
+ .sheet-in .grab { display: block; width: 36px; height: 4px; margin: 0 auto 4px; border-radius: 4px; background: var(--border); }
360
+ .toasts { left: 12px; right: 12px; bottom: calc(12px + var(--safe-b)); }
361
+ .toast { max-width: none; }
362
+ body.chat-mode .toasts { bottom: calc(84px + var(--safe-b)); }
363
+ .tour-card.top, .tour-card.bottom { left: 12px; right: 12px; width: auto; max-height: 46vh; overflow-y: auto; padding: 16px; transition: none; }
364
+ .tour-card.bottom { top: auto; bottom: calc(12px + var(--safe-b)); }
365
+ .tour-card.top { top: calc(12px + var(--safe-t)); bottom: auto; }
366
+ .tour-card.center { max-height: calc(100dvh - 32px); overflow-y: auto; }
367
+ .tour-card h3 { font-size: 18px; }
368
+ .tour-foot .btn { height: 36px; padding: 0 14px; font-size: 13px; }
369
+ .board-root { height: calc(100dvh - 56px - var(--safe-t)) !important; }
370
+ }
371
+
372
+ /* Ordinadors, QR i git */
373
+ .conn.switch { cursor: pointer; border-radius: 8px; transition: color .2s; }
374
+ .conn.switch:hover { color: var(--fg); }
375
+ .conn.switch .ico { width: 14px; height: 14px; flex: none; }
376
+ .switch-chip { margin-top: 10px; cursor: pointer; }
377
+ .switch-chip .ico { width: 14px; height: 14px; }
378
+ .panel.hint { margin-bottom: 20px; padding: 16px 18px; }
379
+ .qr-box { width: min(260px, 100%); margin: 0 auto; padding: 14px; border-radius: 16px; background: #fffefd; border: 1px solid var(--border); }
380
+ .qr-box svg { display: block; width: 100%; height: auto; }
381
+ #ghWrap input[type="search"] { margin-bottom: 4px; }
Binary file