@import url("https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400;600&family=Space+Grotesk:wght@600&display=swap"); :root { --bg-base: #F5F7FA; --bg-panel: #FFFFFF; --bg-panel-alt: color-mix(in srgb, #F5F7FA 78%, #FFFFFF); --border: color-mix(in srgb, #2B2B2B 14%, #FFFFFF); --teal-900: #0A2F5A; --teal-700: color-mix(in srgb, #0A2F5A 78%, #2B2B2B); --teal-100: color-mix(in srgb, #0A2F5A 12%, #FFFFFF); --accent: #F28C28; --accent-light: color-mix(in srgb, #F28C28 14%, #FFFFFF); --text-primary: #2B2B2B; --text-secondary: color-mix(in srgb, #2B2B2B 72%, #FFFFFF); --text-on-dark: #FFFFFF; --status-production: #0A2F5A; --status-unqualified: #F28C28; --status-qualified: #2B2B2B; --status-setup: color-mix(in srgb, #0A2F5A 72%, #F28C28); --status-off-plan: color-mix(in srgb, #2B2B2B 48%, #FFFFFF); --live-indicator: #0A5A21; --cycle-bar-normal: #F9F9F9; --text-xs: 0.75rem; --text-sm: 0.875rem; --text-base: 1rem; --text-lg: 1.125rem; --text-xl: 1.25rem; --text-2xl: 1.5rem; --text-3xl: 2rem; color: var(--text-primary); background: var(--bg-base); font-family: "Instrument Sans", sans-serif; font-size: var(--text-base); font-weight: 400; } * { box-sizing: border-box; } body { margin: 0; min-width: 320px; min-height: 100vh; background: var(--bg-base); } button, input, select, textarea { font: inherit; } button { cursor: pointer; } button:disabled { cursor: not-allowed; } .app-shell { min-height: 100vh; padding: 24px; } .app-shell--workshop { padding: 12px; } .app-shell--workshop .hero, .app-shell--workshop .summary-ribbon, .app-shell--workshop .module-tabs { display: none; } .app-shell--workshop .workspace { width: 100%; } .app-shell--workshop .panel { min-height: calc(100vh - 24px); } .app-shell--workshop .machine-grid { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); } .workspace { display: grid; width: min(1480px, 100%); margin: 0 auto; gap: 18px; align-items: start; } .hero, .panel, .machine-card, .kpi-block { border: 1px solid var(--border); border-radius: 12px; background: var(--bg-panel); box-shadow: 0 1px 3px rgba(10, 47, 90, 0.06), 0 4px 12px rgba(10, 47, 90, 0.04); } .hero { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 20px; } .hero h1 { margin: 0; font-family: "Space Grotesk", sans-serif; font-size: var(--text-3xl); font-weight: 600; line-height: 1.1; letter-spacing: 0; } .hero__status { display: inline-flex; min-height: 44px; align-items: center; gap: 8px; padding: 8px 12px; border-radius: 8px; background: var(--teal-900); color: var(--text-on-dark); font-weight: 600; } .hero__status p { margin: 0; color: var(--text-on-dark); font-size: var(--text-xs); } .hero__dot { width: 20px; height: 20px; border-radius: 99px; background: var(--live-indicator); } .connection-banner { padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--accent-light); color: var(--text-primary); font-weight: 600; } .eyebrow, .meta-label, .kpi-block__label, .machine-card__label, th { color: var(--text-secondary); font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; } .eyebrow { display: block; margin: 0 0 6px; } .panel { padding: 16px; } .panel__header { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 14px; } .panel__header h2 { margin: 0; font-family: "Space Grotesk", sans-serif; font-size: var(--text-xl); font-weight: 600; letter-spacing: 0; } .panel-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; } .panel-actions select, .panel-actions button { min-height: 44px; padding: 8px 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-panel); color: var(--text-primary); } .panel-actions button { background: var(--teal-900); color: var(--text-on-dark); font-family: "Space Grotesk", sans-serif; font-weight: 600; } .summary-ribbon { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; } .module-tabs { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; padding: 8px; border: 1px solid var(--border); border-radius: 12px; background: var(--bg-panel-alt); } .module-tabs__button { display: grid; min-height: 66px; align-content: center; gap: 3px; padding: 10px 12px; border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--text-primary); text-align: left; } .module-tabs__button span { font-family: "Space Grotesk", sans-serif; font-size: var(--text-base); font-weight: 600; } .module-tabs__button small { color: var(--text-secondary); font-size: var(--text-xs); } .module-tabs__button:hover, .module-tabs__button.is-active { border-color: var(--border); background: var(--bg-panel); box-shadow: 0 1px 3px rgba(10, 47, 90, 0.06), 0 4px 12px rgba(10, 47, 90, 0.04); } .module-tabs__button.is-active { box-shadow: inset 0 -3px 0 var(--accent), 0 1px 3px rgba(10, 47, 90, 0.06), 0 4px 12px rgba(10, 47, 90, 0.04); } .module-view { min-width: 0; } .module-grid { display: grid; gap: 14px; } .module-grid--split { grid-template-columns: 1.4fr 0.8fr; } .module-grid--form-table { grid-template-columns: minmax(280px, 380px) minmax(0, 1fr); align-items: start; } .module-form, .config-form { padding: 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-panel-alt); } .config-form { grid-template-columns: repeat(2, minmax(0, 1fr)); } .config-form .checkbox-field, .config-form .primary-button, .config-form .inline-toast { grid-column: 1 / -1; } .kpi-block { min-height: 96px; padding: 14px; } .kpi-block--dark { background: var(--teal-900); color: var(--text-on-dark); } .kpi-block--dark .kpi-block__label, .kpi-block--dark .kpi-block__sub-label { color: var(--text-on-dark); } .kpi-block__label, .kpi-block__sub-label { display: block; } .kpi-block__value { display: block; margin-top: 6px; font-family: "Space Grotesk", sans-serif; font-size: var(--text-2xl); font-weight: 600; line-height: 1.15; letter-spacing: 0; } .kpi-block__sub-label { margin-top: 4px; color: var(--text-secondary); font-size: var(--text-xs); } .machine-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; } .machine-card { display: block; width: 100%; min-height: 180px; overflow: hidden; padding: 0; color: var(--text-primary); text-align: left; transition: box-shadow 160ms ease, transform 160ms ease; } .machine-card__select { display: block; width: 100%; padding: 14px; border: 0; background: transparent; color: var(--text-primary); text-align: left; } .machine-card:hover, .machine-card.is-selected { transform: translateY(-1px); box-shadow: 0 4px 16px rgba(10, 47, 90, 0.12), 0 0 0 2px var(--accent); } .machine-card__top, .machine-card__hero, .machine-card__progress-head { display: flex; justify-content: space-between; gap: 12px; } .machine-card__status-stack { display: grid; justify-items: end; gap: 6px; } .machine-card__code { margin: 0; font-family: "Space Grotesk", sans-serif; font-size: var(--text-xl); font-weight: 600; letter-spacing: 0; } .machine-card__meta { margin: 4px 0 0; color: var(--text-secondary); font-size: var(--text-sm); } .machine-card__hero { margin-top: 12px; padding: 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-panel-alt); } .machine-card__hero strong { display: block; margin-top: 4px; font-size: var(--text-base); } .machine-card__empty { display: grid; gap: 4px; margin-top: 12px; padding: 12px; border: 1px solid var(--border); border-radius: 6px; background: var(--accent-light); } .machine-card__empty strong { font-family: "Space Grotesk", sans-serif; font-size: var(--text-lg); } .machine-card__empty span { color: var(--text-secondary); font-size: var(--text-sm); } .machine-card__stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 12px; margin-top: 12px; } .machine-card__stats span, .machine-card__progress span { display: block; margin-bottom: 3px; color: var(--text-secondary); font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; } .machine-card__stats strong { display: block; min-width: 0; overflow-wrap: anywhere; font-size: var(--text-sm); } .machine-card__progress { margin-top: 12px; } .machine-card__actions { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; border-top: 1px solid var(--border); background: var(--border); } .machine-card__actions button { min-height: 44px; border: 0; background: var(--bg-panel-alt); color: var(--text-primary); font-size: var(--text-sm); font-weight: 600; } .machine-card__actions button:hover:not(:disabled) { background: var(--accent-light); } .progress-track { height: 6px; margin-top: 8px; overflow: hidden; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-panel-alt); } .progress-track progress { display: block; width: 100%; height: 100%; appearance: none; border: 0; } .progress-track progress::-webkit-progress-bar { background: var(--bg-panel-alt); } .progress-track progress::-webkit-progress-value { background: var(--teal-700); } .progress-track progress::-moz-progress-bar { background: var(--teal-700); } .status-badge { display: inline-flex; min-height: 24px; align-items: center; padding: 4px 8px; border-radius: 99px; color: var(--text-on-dark); font-size: var(--text-xs); font-weight: 600; white-space: nowrap; } .duration-badge { display: inline-flex; min-height: 24px; align-items: center; padding: 4px 8px; border: 1px solid var(--border); border-radius: 99px; background: var(--bg-panel-alt); color: var(--text-secondary); font-size: var(--text-xs); font-weight: 600; white-space: nowrap; } .status-badge--production { background: var(--status-production); } .status-badge--arret_non_qualifie { background: var(--status-unqualified); } .status-badge--arret_qualifie { background: var(--status-qualified); } .status-badge--reglage { background: var(--status-setup); } .status-badge--hors_planning { background: var(--status-off-plan); } .detail-stack { display: grid; gap: 14px; } .metric-row, .oee-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; } .machine-context { display: grid; grid-template-columns: 1.2fr 1.6fr 0.8fr; gap: 12px; padding: 12px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-panel-alt); } .machine-context strong { display: block; margin-top: 4px; overflow-wrap: anywhere; } .cycle-panel { padding: 12px; border: 1px solid var(--border); border-radius: 6px; background: var(--teal-900); color: var(--text-on-dark); } .cycle-panel__header { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; } .cycle-panel h3 { margin: 0; font-family: "Space Grotesk", sans-serif; font-size: var(--text-lg); font-weight: 600; } .cycle-panel span { color: var(--text-on-dark); font-size: var(--text-xs); } .cycle-chart { display: block; width: 100%; min-height: 150px; border-radius: 6px; background: var(--teal-700); } .cycle-chart--empty { display: grid; min-height: 150px; place-items: center; border: 1px solid var(--border); color: var(--text-on-dark); } .cycle-chart__reference { stroke: var(--teal-100); stroke-width: 2; stroke-dasharray: 5 5; } .cycle-chart__bar { fill: var(--cycle-bar-normal); } .cycle-chart__bar--slow { fill: var(--status-unqualified); } .detail-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; } .detail-columns h3 { margin: 0 0 10px; font-family: "Space Grotesk", sans-serif; font-size: var(--text-lg); font-weight: 600; } .list { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; } .list li { display: flex; justify-content: space-between; gap: 12px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-panel-alt); } .list li strong { min-width: 0; overflow-wrap: anywhere; } .list li span { flex: 0 0 auto; color: var(--text-secondary); font-size: var(--text-xs); text-align: right; } .timeline-list { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; } .timeline-list li { position: relative; display: flex; justify-content: space-between; gap: 12px; padding: 12px 12px 12px 28px; border-bottom: 1px solid var(--border); } .timeline-list li::before { position: absolute; top: 18px; left: 8px; width: 9px; height: 9px; border-radius: 99px; background: var(--status-unqualified); content: ""; } .timeline-list li::after { position: absolute; top: 29px; bottom: 0; left: 12px; width: 1px; background: var(--border); content: ""; } .timeline-list li:last-child { border-bottom: 0; } .timeline-list li:last-child::after { display: none; } .timeline-list strong, .timeline-list span { display: block; } .timeline-list span, .timeline-list time { color: var(--text-secondary); font-size: var(--text-xs); } .timeline-list time { flex: 0 0 auto; text-align: right; } .oee-mini-list { display: grid; gap: 8px; margin-top: 12px; } .oee-mini-list__item { display: flex; justify-content: space-between; gap: 12px; width: 100%; padding: 8px 10px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-panel-alt); color: var(--text-primary); text-align: left; } .oee-mini-list__item span { color: var(--text-secondary); font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; } .form-grid { display: grid; gap: 10px; } .form-grid input, .form-grid select, .form-grid textarea { width: 100%; min-height: 44px; padding: 8px 12px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-panel); color: var(--text-primary); } .form-grid textarea { resize: vertical; } .checkbox-field { display: flex; min-height: 44px; align-items: center; gap: 8px; padding: 8px 12px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-panel); } .checkbox-field input { width: 18px; height: 18px; } .primary-button, table button { min-height: 44px; padding: 10px 20px; border: 0; border-radius: 8px; background: var(--accent); color: var(--bg-panel); font-family: "Space Grotesk", sans-serif; font-weight: 600; } .primary-button:disabled { opacity: 0.55; } .inline-toast { padding: 8px 10px; border-radius: 6px; background: var(--status-production); color: var(--bg-panel); font-size: var(--text-sm); font-weight: 600; } .inline-error, .field-error { color: var(--status-qualified); font-size: var(--text-sm); } .inline-error { padding: 8px 10px; border: 1px solid var(--status-qualified); border-radius: 6px; background: var(--bg-panel); font-weight: 600; } .field-error { display: block; grid-column: 1 / -1; margin-top: -6px; } .empty-state { padding: 16px; border: 1px dashed var(--border); border-radius: 8px; background: var(--bg-panel-alt); color: var(--text-secondary); font-size: var(--text-sm); font-weight: 600; } .table-wrap { overflow-x: auto; } table { width: 100%; border-collapse: collapse; } th, td { padding: 10px; border-bottom: 1px solid var(--border); text-align: left; } td { font-size: var(--text-sm); } .table-actions { display: flex; gap: 8px; } @media (max-width: 1279px) { .workspace { grid-template-columns: 1fr; } .summary-ribbon { grid-template-columns: repeat(2, minmax(0, 1fr)); } .module-tabs { grid-template-columns: repeat(4, minmax(0, 1fr)); } .module-grid--split, .module-grid--form-table { grid-template-columns: 1fr; } } @media (max-width: 767px) { .app-shell { padding: 12px; } .hero, .machine-card__top, .machine-card__hero, .machine-card__progress-head, .cycle-panel__header, .list li, .timeline-list li { display: grid; } .machine-card__status-stack { justify-items: start; } .panel-actions { justify-content: stretch; } .panel-actions select, .panel-actions button { width: 100%; } .summary-ribbon, .module-tabs, .metric-row, .oee-grid, .machine-context, .detail-columns, .config-form { grid-template-columns: 1fr; } .table-actions { flex-direction: column; } } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; } }