Rediseño impeccable v2: refresh visual de todo el sistema
Segunda iteración del rediseño (sesión separada con skill impeccable). Toca prácticamente toda la UI: layout base, tokens (global.css), todas las páginas de alumno y admin, componentes de solicitudes, inventario, catálogo, filtros, toaster y modales. Docs y sistema: - DESIGN.md y PRODUCT.md actualizados con la nueva iteración. - .impeccable/design.json refleja tokens vigentes. - .impeccable/review/ contiene screenshots de la revisión visual. Dependencias: - Añade @fontsource-variable/jetbrains-mono (fuente monoespaciada). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+81
-148
@@ -1,99 +1,30 @@
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"generatedAt": "2026-08-16T00:00:00Z",
|
||||
"generatedAt": "2026-08-16T00:00:00.000Z",
|
||||
"title": "Design System: LabPréstamos",
|
||||
"extensions": {
|
||||
"colorMeta": {
|
||||
"verde-institucional": {
|
||||
"role": "primary",
|
||||
"displayName": "Verde Institucional",
|
||||
"canonical": "oklch(48.5% 0.12 154.8)",
|
||||
"tonalRamp": [
|
||||
"oklch(15% 0.12 154.8)",
|
||||
"oklch(28% 0.12 154.8)",
|
||||
"oklch(40% 0.12 154.8)",
|
||||
"oklch(52% 0.12 154.8)",
|
||||
"oklch(65% 0.12 154.8)",
|
||||
"oklch(76% 0.12 154.8)",
|
||||
"oklch(86% 0.12 154.8)",
|
||||
"oklch(95% 0.12 154.8)"
|
||||
]
|
||||
},
|
||||
"dorado-uabc": {
|
||||
"role": "secondary",
|
||||
"displayName": "Dorado UABC",
|
||||
"canonical": "oklch(72.8% 0.148 74.4)",
|
||||
"tonalRamp": [
|
||||
"oklch(15% 0.148 74.4)",
|
||||
"oklch(28% 0.148 74.4)",
|
||||
"oklch(40% 0.148 74.4)",
|
||||
"oklch(52% 0.148 74.4)",
|
||||
"oklch(65% 0.148 74.4)",
|
||||
"oklch(76% 0.148 74.4)",
|
||||
"oklch(86% 0.148 74.4)",
|
||||
"oklch(95% 0.148 74.4)"
|
||||
]
|
||||
},
|
||||
"superficie": {
|
||||
"role": "neutral",
|
||||
"displayName": "Superficie",
|
||||
"canonical": "oklch(97.3% 0.004 157.2)",
|
||||
"tonalRamp": [
|
||||
"oklch(15% 0.004 157.2)",
|
||||
"oklch(28% 0.004 157.2)",
|
||||
"oklch(40% 0.004 157.2)",
|
||||
"oklch(52% 0.004 157.2)",
|
||||
"oklch(65% 0.004 157.2)",
|
||||
"oklch(76% 0.004 157.2)",
|
||||
"oklch(86% 0.004 157.2)",
|
||||
"oklch(95% 0.004 157.2)"
|
||||
]
|
||||
},
|
||||
"tinta": {
|
||||
"role": "neutral",
|
||||
"displayName": "Tinta",
|
||||
"canonical": "oklch(33.5% 0.033 260.9)",
|
||||
"tonalRamp": [
|
||||
"oklch(15% 0.033 260.9)",
|
||||
"oklch(28% 0.033 260.9)",
|
||||
"oklch(40% 0.033 260.9)",
|
||||
"oklch(52% 0.033 260.9)",
|
||||
"oklch(65% 0.033 260.9)",
|
||||
"oklch(76% 0.033 260.9)",
|
||||
"oklch(86% 0.033 260.9)",
|
||||
"oklch(95% 0.033 260.9)"
|
||||
]
|
||||
},
|
||||
"peligro": {
|
||||
"role": "danger",
|
||||
"displayName": "Peligro",
|
||||
"canonical": "oklch(54.4% 0.186 26)",
|
||||
"tonalRamp": [
|
||||
"oklch(15% 0.186 26)",
|
||||
"oklch(28% 0.186 26)",
|
||||
"oklch(40% 0.186 26)",
|
||||
"oklch(52% 0.186 26)",
|
||||
"oklch(65% 0.186 26)",
|
||||
"oklch(76% 0.186 26)",
|
||||
"oklch(86% 0.186 26)",
|
||||
"oklch(95% 0.186 26)"
|
||||
]
|
||||
}
|
||||
"cream": { "role": "neutral", "displayName": "Cream Paper", "canonical": "#f4efea" },
|
||||
"frost": { "role": "neutral", "displayName": "Frost White", "canonical": "#ffffff" },
|
||||
"chalk": { "role": "neutral", "displayName": "Chalk Gray", "canonical": "#f8f8f7" },
|
||||
"ink": { "role": "neutral", "displayName": "Charcoal Ink", "canonical": "#383838" },
|
||||
"pencil": { "role": "neutral", "displayName": "Pencil Gray", "canonical": "#a1a1a1" },
|
||||
"primary": { "role": "primary", "displayName": "Sky Crayon", "canonical": "#6fc2ff" },
|
||||
"secondary": { "role": "secondary", "displayName": "Duck Bill Orange", "canonical": "#ff9538" },
|
||||
"danger": { "role": "danger", "displayName": "Coral Sketch (fill)", "canonical": "#f38e84" },
|
||||
"danger-text": { "role": "danger", "displayName": "Coral Sketch (text, AA-darkened)", "canonical": "#a83224" },
|
||||
"positive": { "role": "success", "displayName": "Mint Sketch", "canonical": "#38c1b0" }
|
||||
},
|
||||
"typographyMeta": {
|
||||
"headline": { "displayName": "Headline", "purpose": "Page-level h1 — dashboard/section titles, login title." },
|
||||
"title": { "displayName": "Title", "purpose": "Card and section headers within a page." },
|
||||
"body": { "displayName": "Body", "purpose": "Default text size across the whole system: table cells, descriptions, list content." },
|
||||
"label": { "displayName": "Label", "purpose": "Form field labels, always paired with htmlFor/id." },
|
||||
"caption": { "displayName": "Caption", "purpose": "Metadata: matrícula, inventory numbers, timestamps, field hints." }
|
||||
"body": { "displayName": "Body / Mono", "purpose": "Universal voice — every role through weight, size, and case." },
|
||||
"label": { "displayName": "Label", "purpose": "Uppercase structural labels: nav, buttons, form labels, headers." }
|
||||
},
|
||||
"shadows": [
|
||||
{ "name": "floating-chrome", "value": "0 10px 30px -8px rgba(0,0,0,0.25)", "purpose": "Mobile dock nav — soft ambient shadow signaling it floats above the scrolling page." },
|
||||
{ "name": "overlay-notification", "value": "0 16px 40px -12px rgba(0,0,0,0.25)", "purpose": "Toast stack — same ambient quality, slightly heavier, paired with backdrop-blur-xl." }
|
||||
{ "name": "hard", "value": "-6px 6px 0 0 #383838", "purpose": "The system's only shadow — every raised element at rest." },
|
||||
{ "name": "hard-sm", "value": "-3px 3px 0 0 #383838", "purpose": "Active/pressed state of a raised element (halfway press)." }
|
||||
],
|
||||
"motion": [
|
||||
{ "name": "toast-entrance", "value": "cubic-bezier(0.22, 1, 0.36, 1)", "purpose": "260ms translate+scale+fade entrance for toast notifications." },
|
||||
{ "name": "chrome-transition", "value": "cubic-bezier(0, 0, 0.2, 1)", "purpose": "150-200ms default ease-out for sidebar collapse, hover states, dock icon transitions." }
|
||||
{ "name": "press", "value": "transform: translate(-6px, 6px); transition: transform 100ms ease-out;", "purpose": "Hover/focus on any raised element — presses into its own shadow." }
|
||||
],
|
||||
"breakpoints": [
|
||||
{ "name": "md", "value": "768px" }
|
||||
@@ -104,100 +35,102 @@
|
||||
"name": "Primary Button",
|
||||
"kind": "button",
|
||||
"refersTo": "button-primary",
|
||||
"description": "Default call to action: submit, approve, continue with Google.",
|
||||
"html": "<button class=\"ds-btn ds-btn-primary\">Enviar solicitud</button>",
|
||||
"css": ".ds-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 10px 16px; border-radius: 8px; font-weight: 500; font-size: 0.875rem; border: none; cursor: pointer; touch-action: manipulation; transition: filter 150ms ease-out, background-color 150ms ease-out; } .ds-btn-primary { background: #00723F; color: #ffffff; } .ds-btn-primary:hover { filter: brightness(1.1); } .ds-btn-primary:focus-visible { outline: 2px solid #00723F; outline-offset: 2px; } .ds-btn-primary:disabled { opacity: 0.5; pointer-events: none; }"
|
||||
"description": "The system's default call to action.",
|
||||
"html": "<button class=\"ds-btn ds-btn-primary\">Solicitar</button>",
|
||||
"css": ".ds-btn { display:inline-flex; align-items:center; justify-content:center; gap:8px; min-height:44px; padding:10px 16px; border-radius:2px; border:2px solid #383838; font-family:'JetBrains Mono Variable',monospace; letter-spacing:0.02em; font-weight:500; box-shadow:-6px 6px 0 0 #383838; transition:transform 100ms ease-out; } .ds-btn:hover, .ds-btn:focus-visible { transform:translate(-6px,6px); box-shadow:0 0 0 0 transparent; } .ds-btn-primary { background:#6fc2ff; color:#383838; }"
|
||||
},
|
||||
{
|
||||
"name": "Secondary Button",
|
||||
"kind": "button",
|
||||
"refersTo": "button-secondary",
|
||||
"description": "Sparingly used accent action — filtering, non-primary confirms.",
|
||||
"html": "<button class=\"ds-btn ds-btn-secondary\">Filtrar</button>",
|
||||
"css": ".ds-btn-secondary { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 10px 16px; border-radius: 8px; font-weight: 500; font-size: 0.875rem; border: none; cursor: pointer; touch-action: manipulation; background: #DD971A; color: #ffffff; transition: filter 150ms ease-out; } .ds-btn-secondary:hover { filter: brightness(1.1); } .ds-btn-secondary:focus-visible { outline: 2px solid #00723F; outline-offset: 2px; }"
|
||||
"description": "White-filled, charcoal-outlined — never a second brand color.",
|
||||
"html": "<button class=\"ds-btn ds-btn-secondary\">Exportar CSV</button>",
|
||||
"css": ".ds-btn-secondary { background:#ffffff; color:#383838; }"
|
||||
},
|
||||
{
|
||||
"name": "Ghost Button",
|
||||
"kind": "button",
|
||||
"refersTo": "button-ghost",
|
||||
"description": "Low-commitment counterpart to Primary — cancel, clear filters.",
|
||||
"html": "<button class=\"ds-btn ds-btn-ghost\">Cancelar</button>",
|
||||
"css": ".ds-btn-ghost { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 10px 16px; border-radius: 8px; font-weight: 500; font-size: 0.875rem; cursor: pointer; touch-action: manipulation; background: transparent; color: #2D3748; border: 1px solid color-mix(in oklab, #2D3748 15%, transparent); transition: background-color 150ms ease-out; } .ds-btn-ghost:hover { background: color-mix(in oklab, #2D3748 5%, transparent); } .ds-btn-ghost:focus-visible { outline: 2px solid #00723F; outline-offset: 2px; }"
|
||||
"description": "Low-commitment counterpart — Cancelar/Limpiar.",
|
||||
"html": "<button class=\"ds-btn-ghost\">Cancelar</button>",
|
||||
"css": ".ds-btn-ghost { display:inline-flex; align-items:center; justify-content:center; gap:8px; min-height:44px; padding:10px 16px; border-radius:2px; border:2px solid rgba(56,56,56,0.35); background:transparent; color:#383838; font-family:'JetBrains Mono Variable',monospace; letter-spacing:0.02em; font-weight:500; } .ds-btn-ghost:hover { background:#f8f8f7; border-color:#383838; }"
|
||||
},
|
||||
{
|
||||
"name": "Status Pill",
|
||||
"kind": "chip",
|
||||
"refersTo": "badge",
|
||||
"description": "Tinted-fill status indicator used for every préstamo/material estado; solid-fill only for the confirmed Vencido exception.",
|
||||
"html": "<span class=\"ds-pill ds-pill-primary\">Disponible</span> <span class=\"ds-pill ds-pill-secondary\">Mantenimiento</span> <span class=\"ds-pill ds-pill-danger-solid\">Vencido</span>",
|
||||
"css": ".ds-pill { display: inline-flex; align-items: center; border-radius: 9999px; padding: 2px 10px; font-size: 0.75rem; font-weight: 600; white-space: nowrap; } .ds-pill-primary { background: color-mix(in oklab, #00723F 13%, transparent); color: #00723F; } .ds-pill-secondary { background: color-mix(in oklab, #DD971A 15%, transparent); color: #c78614; } .ds-pill-danger-solid { background: #C53030; color: #ffffff; }"
|
||||
},
|
||||
{
|
||||
"name": "Card",
|
||||
"name": "Raised Card",
|
||||
"kind": "card",
|
||||
"refersTo": "card",
|
||||
"description": "Flat white container — the system's default surface for content, forms, and KPI tiles. No shadow, hairline ink-mix border only.",
|
||||
"html": "<div class=\"ds-card\"><h3 class=\"ds-card-title\">Inicia sesión</h3><p class=\"ds-card-body\">Accede con tu cuenta institucional.</p></div>",
|
||||
"css": ".ds-card { background: #ffffff; border-radius: 8px; padding: 24px; border: 1px solid color-mix(in oklab, #2D3748 10%, transparent); } .ds-card-title { font-size: 1.125rem; font-weight: 600; margin: 0 0 4px; color: #2D3748; } .ds-card-body { font-size: 0.875rem; opacity: 0.7; margin: 0; color: #2D3748; }"
|
||||
"description": "Discrete, singular, actionable surface — login card, dashboard tile, KPI tile.",
|
||||
"html": "<a class=\"ds-card-raised\" href=\"#\"><h2>Catálogo</h2><p>Ver material disponible.</p></a>",
|
||||
"css": ".ds-card-raised { display:block; background:#ffffff; border:2px solid #383838; border-radius:2px; padding:24px; box-shadow:-6px 6px 0 0 #383838; transition:transform 100ms ease-out; } .ds-card-raised:hover, .ds-card-raised:focus-visible { transform:translate(-6px,6px); box-shadow:0 0 0 0 transparent; } .ds-card-raised h2 { font-family:'JetBrains Mono Variable',monospace; text-transform:uppercase; letter-spacing:0.02em; font-size:1.125rem; margin:0 0 4px; color:#383838; } .ds-card-raised p { color:#a1a1a1; font-family:'JetBrains Mono Variable',monospace; font-size:0.875rem; margin:0; }"
|
||||
},
|
||||
{
|
||||
"name": "Input Field",
|
||||
"name": "Flat Card / Table Wrapper",
|
||||
"kind": "card",
|
||||
"refersTo": "card",
|
||||
"description": "Dense, repeated content — tables, list rows. Bordered, no shadow.",
|
||||
"html": "<div class=\"ds-card-flat\">Fila de tabla o lista</div>",
|
||||
"css": ".ds-card-flat { background:#ffffff; border:1.5px solid #383838; border-radius:2px; padding:24px; font-family:'JetBrains Mono Variable',monospace; color:#383838; }"
|
||||
},
|
||||
{
|
||||
"name": "Text Input",
|
||||
"kind": "input",
|
||||
"refersTo": "input",
|
||||
"description": "Labeled text field with hairline border and single-color focus outline (no glow, no border-color shift).",
|
||||
"html": "<div class=\"ds-field\"><label class=\"ds-label\" for=\"demo-input\">Cantidad</label><input id=\"demo-input\" class=\"ds-input\" type=\"number\" value=\"1\" /></div>",
|
||||
"css": ".ds-label { display: block; font-size: 0.875rem; font-weight: 500; margin-bottom: 4px; color: color-mix(in oklab, #2D3748 90%, transparent); } .ds-input { width: 100%; min-height: 44px; border-radius: 8px; padding: 10px 12px; background: #ffffff; border: 1px solid color-mix(in oklab, #2D3748 20%, transparent); font-size: 0.875rem; touch-action: manipulation; transition: border-color 150ms, box-shadow 150ms; } .ds-input:focus-visible { outline: 2px solid #00723F; outline-offset: 2px; }"
|
||||
"description": "Flat, bordered, no shadow, no glow focus.",
|
||||
"html": "<input class=\"ds-input\" type=\"text\" placeholder=\"Nombre o Nº inventario…\" />",
|
||||
"css": ".ds-input { width:100%; min-height:44px; padding:10px 12px; border-radius:2px; border:2px solid #383838; background:#ffffff; font-family:'JetBrains Mono Variable',monospace; color:#383838; } .ds-input:focus { outline:none; border-color:#6fc2ff; }"
|
||||
},
|
||||
{
|
||||
"name": "Mobile Dock Nav Item",
|
||||
"name": "Status Badge",
|
||||
"kind": "chip",
|
||||
"refersTo": "badge",
|
||||
"description": "Tinted fill, semantic-color border, always charcoal text.",
|
||||
"html": "<span class=\"ds-badge ds-badge-positive\">Disponible</span>",
|
||||
"css": ".ds-badge { display:inline-flex; align-items:center; border-radius:2px; padding:2px 8px; font-family:'JetBrains Mono Variable',monospace; font-size:0.75rem; font-weight:600; text-transform:uppercase; letter-spacing:0.03em; color:#383838; } .ds-badge-positive { background:color-mix(in oklab, #38c1b0 18%, white); border:1.5px solid #38c1b0; } .ds-badge-danger { background:color-mix(in oklab, #f38e84 18%, white); border:1.5px solid #f38e84; }"
|
||||
},
|
||||
{
|
||||
"name": "Nav Item (desktop sidebar)",
|
||||
"kind": "nav",
|
||||
"refersTo": "nav-dock-item",
|
||||
"description": "Signature component: icon-only floating pill navigation for the alumno/admin mobile layout, replacing a conventional bottom tab bar.",
|
||||
"html": "<nav class=\"ds-dock\"><a href=\"#\" class=\"ds-dock-item ds-dock-item-active\" aria-label=\"Inicio\"><svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M2.25 12l8.954-8.955a1.5 1.5 0 012.122 0L22.28 12M4.5 9.75v10.125A1.125 1.125 0 005.625 21H9.75v-6h4.5v6h4.125A1.125 1.125 0 0019.5 19.875V9.75\"/></svg></a><a href=\"#\" class=\"ds-dock-item\" aria-label=\"Catálogo\"><svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3.75 6A2.25 2.25 0 016 3.75h2.25A2.25 2.25 0 0110.5 6v2.25a2.25 2.25 0 01-2.25 2.25H6A2.25 2.25 0 013.75 8.25V6z\"/></svg></a></nav>",
|
||||
"css": ".ds-dock { display: inline-flex; align-items: center; gap: 4px; border-radius: 9999px; padding: 8px; backdrop-filter: blur(8px); background: rgba(255,255,255,0.95); box-shadow: 0 10px 30px -8px rgba(0,0,0,0.25); border: 1px solid color-mix(in oklab, #2D3748 10%, transparent); } .ds-dock-item { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 9999px; color: color-mix(in oklab, #2D3748 70%, transparent); transition: background-color 150ms, color 150ms, transform 150ms; text-decoration: none; } .ds-dock-item:hover { background: color-mix(in oklab, #2D3748 5%, transparent); color: #2D3748; } .ds-dock-item:active { transform: scale(0.95); } .ds-dock-item-active { background: #00723F; color: #ffffff; }"
|
||||
},
|
||||
{
|
||||
"name": "Toast",
|
||||
"kind": "custom",
|
||||
"refersTo": "toast",
|
||||
"description": "Signature component: floating top-center notification with a colored circular icon chip, survives page reload via a sessionStorage queue.",
|
||||
"html": "<div class=\"ds-toast\"><span class=\"ds-toast-icon\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4.5 12.75l6 6 9-13.5\"/></svg></span><span class=\"ds-toast-text\"><span class=\"ds-toast-title\">Solicitud enviada</span><span class=\"ds-toast-desc\">Multímetro digital · pendiente de aprobación</span></span></div>",
|
||||
"css": ".ds-toast { display: flex; align-items: flex-start; gap: 12px; border-radius: 16px; padding: 12px 16px; background: rgba(255,255,255,0.85); backdrop-filter: blur(20px); box-shadow: 0 16px 40px -12px rgba(0,0,0,0.25); border: 1px solid color-mix(in oklab, #2D3748 10%, transparent); color: #2D3748; max-width: 26rem; } .ds-toast-icon { flex-shrink: 0; display: grid; place-items: center; width: 36px; height: 36px; border-radius: 9999px; background: #00723F; color: #ffffff; } .ds-toast-title { display: block; font-weight: 600; font-size: 0.875rem; } .ds-toast-desc { display: block; font-size: 0.75rem; opacity: 0.7; margin-top: 2px; }"
|
||||
"refersTo": "nav-item",
|
||||
"description": "Uppercase mono label; active = solid Sky Crayon chip with charcoal border.",
|
||||
"html": "<a class=\"ds-nav-item ds-nav-item-active\" href=\"#\">Catálogo</a>",
|
||||
"css": ".ds-nav-item { display:flex; align-items:center; gap:12px; padding:10px 12px; border-radius:2px; border:2px solid transparent; font-family:'JetBrains Mono Variable',monospace; text-transform:uppercase; letter-spacing:0.02em; font-size:0.875rem; color:#383838; } .ds-nav-item-active { background:#6fc2ff; border-color:#383838; } .ds-nav-item:not(.ds-nav-item-active):hover { background:#f8f8f7; }"
|
||||
}
|
||||
],
|
||||
"narrative": {
|
||||
"northStar": "La Bitácora Digital",
|
||||
"overview": "LabPréstamos is the printed loan sheet and the Excel logbook it used to feed, collapsed into one live surface. Every visual decision defends that lineage: nothing decorative, nothing that would feel out of place next to an official UABC form, but nothing that feels like a cold spreadsheet either. The system is cálido pero confiable — warm but reliable — and it earns the \"warm\" half narrowly: a gold accent, soft rounded corners, and gentle motion sit on top of an otherwise flat, administrative base.\n\nThe page itself stays flat and quiet — white cards on a pale green-grey surface, hairline borders instead of shadows, tabular numbers lined up like a real ledger. Depth is reserved for the two things that are genuinely floating above the page: the toast notifications and the mobile navigation dock. That asymmetry is deliberate — it is how the system tells the eye \"this is the document\" from \"this is the chrome.\"\n\nTwo audiences read this bitácora differently. The alumno's default device is the phone — the catalog, the request modal, the pill-shaped floating dock are all tuned for thumbs. The admin's default device is the desktop — dense tables, a persistent sidebar, KPI tiles. Neither view degrades on the other's device; every screen ships both a table and a card-list rendering.",
|
||||
"northStar": "The Equipment Tag on a Terminal Readout",
|
||||
"overview": "LabPréstamos was rebuilt against a fully pinned external brief (MotherDuck's crayon-terminal-on-cream neobrutalism), translated from a marketing site's vocabulary into an operational lab tool's. The identity keeps the source system's mechanics intact — a warm cream canvas, monospace type standing in for a terminal readout, hard 2px corners, and a flat charcoal-offset shadow that never blurs — while dropping what only belonged to marketing (hand-drawn duck illustrations, scrolling marquees, testimonial cards). What replaces the duck is the product's own mark: a loan tag with a punch-hole, echoing the paper ticket this system replaced. Depth here is binary, not a hierarchy: an element either sits flat on the page or it's a discrete raised object that presses into its own shadow on hover. Color plays a stricter role than in the source brief: Sky Crayon blue is reserved for actionable, filled controls; Mint Sketch was pulled from the source's decorative rainbow set and fixed as the positive-status color; Coral Sketch was fixed as the sole danger color, split into a light fill and a separately darkened AA-compliant text variant.",
|
||||
"keyCharacteristics": [
|
||||
"Flat administrative base (white cards, hairline ink-tinted borders, no ambient shadow)",
|
||||
"Shadow appears only on floating overlay chrome — the mobile dock and toasts — never on the page plane",
|
||||
"Every status is a tinted pill: 12–15% color wash background, full-strength text",
|
||||
"Tabular numbers everywhere a quantity, date, or stock figure appears",
|
||||
"One typeface (Inter Variable) carrying every role through weight and size alone",
|
||||
"Motion is a courtesy, not a performance: motion-safe:-gated, specific-property transitions, no transition-all"
|
||||
"Cream page canvas, white card surfaces, charcoal (never pure black) as the universal line, border, and text color",
|
||||
"Every corner is 2px — no pills, no circles, no rounded-full anywhere",
|
||||
"One shadow, one behavior: -6px 6px 0 0 charcoal, hard-edged, flattens into the element on hover/focus",
|
||||
"JetBrains Mono Variable everywhere, 0.02em tracking, uppercase on structural labels only",
|
||||
"Status pills are tinted fills with a matching-color border and always-charcoal text",
|
||||
"Dense, repeated surfaces stay flat and bordered; only discrete, single-instance elements carry the shadow"
|
||||
],
|
||||
"rules": [
|
||||
{ "name": "The Ink-Mix Border Rule", "body": "Every hairline border and divider is color-mix(in oklab, var(--color-tinta) N%, transparent), never a literal gray hex. A border is always \"ink, diluted,\" so it stays coherent with body text at any opacity.", "section": "colors" },
|
||||
{ "name": "The Vencido Exception", "body": "Every status pill uses the tinted-fill pattern except an overdue loan (\"Vencido\"), which gets a solid peligro fill with white text — on both the table badge and, on mobile, a light danger wash across the entire card background. This is the system's one permitted alarm.", "section": "colors" },
|
||||
{ "name": "The Tabular Numbers Rule", "body": "Any figure that represents a count — cantidad, stock (disponible/total), KPI values, dates — is rendered with font-variant-numeric: tabular-nums. Numbers must align like a ledger column.", "section": "typography" },
|
||||
{ "name": "The Table/Card Swap Rule", "body": "Every data-dense admin view ships two complete renderings of the same data: a table for md:block and a card list for md:hidden. This is a structural swap, not a responsive squeeze.", "section": "layout" },
|
||||
{ "name": "The Flat Page, Floating Chrome Rule", "body": "If an element is part of the document (a card, a table, a form), it stays flat with a hairline border. If an element floats above the document regardless of scroll (the dock, a toast), it gets a soft ambient shadow plus backdrop-blur.", "section": "elevation" }
|
||||
{ "name": "The Charcoal Text Rule", "body": "No filled or tinted surface ever carries white or colored text — text is always Charcoal Ink. Color differentiates status and action through background fill and border only.", "section": "colors" },
|
||||
{ "name": "The One Shadow Rule", "body": "-6px 6px 0 0 var(--color-ink) is the only shadow value in the system. It never blurs, never softens, never gets a second 'subtle' variant.", "section": "colors" },
|
||||
{ "name": "The Tabular Numbers Rule", "body": "Any figure representing a count carries font-variant-numeric: tabular-nums.", "section": "typography" },
|
||||
{ "name": "The Press Rule", "body": "Every raised element's hover state is the same transform: translate exactly the shadow's own offset, so the shadow disappears under the element. No brightness filter, no color darken.", "section": "elevation" },
|
||||
{ "name": "The Tinted-Fill-Bordered Rule", "body": "Badge background = the semantic color mixed 18-25% into white; border = the semantic color at full strength; text = Charcoal Ink always.", "section": "components" }
|
||||
],
|
||||
"dos": [
|
||||
"Do use color-mix(in oklab, var(--color-tinta) N%, transparent) for any new border or divider — never a literal gray.",
|
||||
"Do keep shadow exclusive to floating overlay chrome (toasts, the mobile dock).",
|
||||
"Do use the tinted-pill pattern (12–15% background, full-strength text) for any new status or state indicator.",
|
||||
"Do apply font-variant-numeric: tabular-nums to any new numeric quantity, stock figure, or date.",
|
||||
"Do ship both a md:block table and a md:hidden card-list rendering for any new data-dense admin view.",
|
||||
"Do gate all motion with motion-safe: and animate specific properties, never transition-all.",
|
||||
"Do give every interactive control a 44px minimum tap target and touch-action: manipulation."
|
||||
"Do use the exact shadow -6px 6px 0 0 var(--color-ink) for every raised element, and the exact press transform translate(-6px, 6px) on hover/focus.",
|
||||
"Do keep every radius at 2px — buttons, cards, inputs, dialogs, badges, chips.",
|
||||
"Do keep text Charcoal Ink on every fill, tint, or border color.",
|
||||
"Do reserve Sky Crayon for actionable, filled controls; use Positive/Danger/Secondary for status.",
|
||||
"Do keep dense/repeated surfaces flat and bordered; reserve the hard shadow for discrete, singular surfaces.",
|
||||
"Do draw every icon as an SVG — never a unicode glyph or emoji.",
|
||||
"Do apply font-variant-numeric: tabular-nums to every numeric quantity, stock figure, or date.",
|
||||
"Do ship both a table and a card-list rendering for every data-dense admin view."
|
||||
],
|
||||
"donts": [
|
||||
"Don't add a shadow to .card, .btn, or .input — the system's flatness on the page plane is deliberate.",
|
||||
"Don't introduce a second typeface. Inter Variable carries every role through weight and size.",
|
||||
"Don't give a status pill a solid saturated fill — the tinted wash is the rule, and Vencido is the one confirmed exception, not a precedent to extend.",
|
||||
"Don't reach for rounded-2xl outside the login mark and toasts; it is reserved for \"first impression / interruption\" moments.",
|
||||
"Don't replace the mobile bottom dock with a hamburger drawer, or the desktop sidebar with a top bar — the device-appropriate nav pattern per breakpoint is deliberate."
|
||||
"Don't use blur, glass, or a soft ambient shadow anywhere.",
|
||||
"Don't introduce a radius above 2px, or a pill/circle shape, anywhere.",
|
||||
"Don't use a second filled brand color for secondary actions.",
|
||||
"Don't reuse Sky Crayon for status pills.",
|
||||
"Don't introduce a second typeface.",
|
||||
"Don't stand a unicode glyph in for an icon."
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user