diff --git a/docs/superpowers/specs/2026-03-20-page1-header-restyle-design.md b/docs/superpowers/specs/2026-03-20-page1-header-restyle-design.md new file mode 100644 index 0000000..34bb318 --- /dev/null +++ b/docs/superpowers/specs/2026-03-20-page1-header-restyle-design.md @@ -0,0 +1,176 @@ +# Design Spec: Page 1 Header Restyle & Label Fixes + +**Date:** 2026-03-20 +**Status:** Approved +**Scope:** `AnagraficaSectionRenderer.cs`, `EventiSectionRenderer.cs`, `PdfTheme.cs` + +--- + +## Overview + +Piccolo insieme di modifiche visive e testuali alla pagina 1 del report PDF e alla sezione eventi, senza alterare la struttura generale del report. + +--- + +## 1. Nuovo layout header Pagina 1 (`AnagraficaSectionRenderer.DrawTitle`) + +### Layout approvato + +``` + Scheda Prodotto XS1234567890 ← centrato, blu bold, font grande +──────────────────────────────────────────────── ← linea separatrice AccentBlue (2pt) +[TIPOLOGIA / Cert. Bonus Cap] [DATA / 18/03/26] [BID / 98.50] [ASK / 99.20] +``` + +### Specifiche riquadri (riga inferiore) + +Tutti i box hanno la **stessa altezza** (28pt) e la **stessa struttura a due righe**: +- Riga 1: label piccola (9pt, uppercase, bold, colore accent), altezza 11pt +- Riga 2: valore (13pt bold, colore accent scuro), altezza 17pt + +Il padding interno è 5pt verticale, 10pt orizzontale (dopo il bordo sinistro da 4pt). + +| Box | Larghezza | Sfondo | Bordo sinistro | Colore label | Colore valore | +|-----|-----------|--------|----------------|--------------|---------------| +| Tipologia | `PageW - 3*6 - 84 - 70 - 70` | `PdfTheme.BoxLightBlueBg` | `PdfTheme.AccentBlue` 4pt | `PdfTheme.AccentBlue` | `PdfTheme.AccentBlueDark` | +| Data | 84pt fisso | `PdfTheme.BoxGrayBg` | `PdfTheme.BoxGrayAccent` 4pt | `PdfTheme.BoxGrayLabel` | `PdfTheme.BoxGrayValue` | +| Bid | 70pt fisso | `PdfTheme.BoxLightBlueBg` | `PdfTheme.AccentBlue` 4pt | `PdfTheme.AccentBlue` | `PdfTheme.AccentBlueDark` | +| Ask | 70pt fisso | `PdfTheme.BoxLightBlueBg` | `PdfTheme.AccentBlue` 4pt | `PdfTheme.AccentBlue` | `PdfTheme.AccentBlueDark` | + +Gap tra box: 6pt. + +### Nuove costanti da aggiungere a `PdfTheme.cs` + +```csharp +public static readonly Color AccentBlueDark = Color.FromArgb(255, 13, 71, 161); // #0D47A1 +public static readonly Color BoxLightBlueBg = Color.FromArgb(255,235,242,251); // #EBF2FB +public static readonly Color BoxGrayBg = Color.FromArgb(255,245,245,245); // #F5F5F5 +public static readonly Color BoxGrayAccent = Color.FromArgb(255,136,136,136); // #888888 +public static readonly Color BoxGrayLabel = Color.FromArgb(255,102,102,102); // #666666 +public static readonly Color BoxGrayValue = Color.FromArgb(255, 51, 51, 51); // #333333 + +// Brush corrispondenti +public static readonly PdfBrush BoxLightBlueBgBrush = new PdfSolidBrush(BoxLightBlueBg); +public static readonly PdfBrush BoxGrayBgBrush = new PdfSolidBrush(BoxGrayBg); +public static readonly PdfBrush BoxGrayAccentBrush = new PdfSolidBrush(BoxGrayAccent); +public static readonly PdfBrush BoxGrayLabelBrush = new PdfSolidBrush(BoxGrayLabel); +public static readonly PdfBrush BoxGrayValueBrush = new PdfSolidBrush(BoxGrayValue); +public static readonly PdfBrush AccentBlueDarkBrush = new PdfSolidBrush(AccentBlueDark); +``` + +### Font per i box + +Riusare i font esistenti in `PdfTheme`: +- Label: `PdfTheme.Small` (9pt) — già esistente +- Valore Bid/Ask/Data: `PdfTheme.Bold` (stesso usato altrove) +- Valore Tipologia: nuovo font `PdfTheme.BoldSmall` (11pt bold) — aggiungere se non esistente, altrimenti usare font bold a 11pt inline + +### Implementazione PDF (Syncfusion) — helper `DrawInfoBox` + +Creare un metodo privato in `AnagraficaSectionRenderer`: + +```csharp +private void DrawInfoBox(PdfGraphics g, float x, float y, float w, float boxH, + string label, string value, + PdfBrush bgBrush, PdfBrush accentBrush, PdfBrush labelBrush, PdfBrush valueBrush, + PdfFont valueFont) +{ + // Sfondo + g.DrawRectangle(bgBrush, new RectangleF(x, y, w, boxH)); + // Bordo sinistro 4pt + g.DrawRectangle(accentBrush, new RectangleF(x, y, 4f, boxH)); + // Label (riga 1) — parte dopo il bordo + padding + float innerX = x + 4f + 6f; + float innerW = w - 4f - 6f - 4f; + g.DrawString(label, PdfTheme.Small, labelBrush, + new RectangleF(innerX, y + 4f, innerW, 11f)); + // Valore (riga 2) + g.DrawString(value, valueFont, valueBrush, + new RectangleF(innerX, y + 14f, innerW, 14f)); +} +``` + +**Nota Syncfusion:** `RectangleF` non supporta named arguments — usare sempre la forma posizionale `new RectangleF(x, y, w, h)`. + +### Gestione casi nulli / vuoti + +- **Bid e Ask**: se `string.IsNullOrEmpty(info.Bid) || string.IsNullOrEmpty(info.Ask)`, i box Bid e Ask **non vengono disegnati**; la larghezza liberata viene assorbita dal box Tipologia. Il box Data viene comunque disegnato se `LastPriceDate` non è vuoto. +- **Data**: se `string.IsNullOrEmpty(info.LastPriceDate)`, il box Data viene omesso. +- **Tipologia**: se `string.IsNullOrEmpty(info.Categoria)`, il box Tipologia viene omesso; in quel caso i box rimanenti (Data/Bid/Ask) si dispongono da sinistra normalmente. + +### Troncamento testo Tipologia + +Il box Tipologia usa `RectangleF` con larghezza calcolata. Syncfusion tronca automaticamente il testo che eccede la `RectangleF` — nessuna logica extra necessaria. Il font 11pt consente fino a ~45 caratteri nella larghezza tipica (~290pt). Per tipologie più lunghe il testo viene tagliato dal renderer PDF senza errori. + +### Rimozione logica precedente + +Il vecchio `DrawTitle` disegnava: +- Titolo a sinistra in `w * 0.65f` + Bid/Ask come stringa a destra in `w * 0.35f` +- Tipologia come riga di testo grigio `Regular` sotto il titolo + +Tutta la logica di `DrawTitle` viene riscritta. Il metodo `DrawTitle` torna `float y` (la nuova y dopo il titolo + linea + box row). + +--- + +## 2. Rinomina colonne Tabella Sottostanti (`AnagraficaSectionRenderer.DrawSottostanti`) + +Modifica solo le stringhe nell'array degli header: + +| Vecchio | Nuovo | +|---------|-------| +| `"Barr.K"` | `"Barriera Capitale"` | +| `"Buffer K"` | `"Buffer Capitale"` | +| `"Trig.CPN"` | `"Trigger Cedola"` | +| `"Buf.CPN"` | `"Buffer Cedola"` | + +Le altre colonne (`Nome`, `Strike`, `Last`, `% Perf.`, `Trig.AC`) rimangono invariate. Le larghezze colonna possono richiedere un piccolo aggiustamento se i nuovi header non entrano — da verificare a runtime. + +--- + +## 3. Rinomina colonna Tabella Eventi (`EventiSectionRenderer`) + +| Vecchio | Nuovo | +|---------|-------| +| `"Trigger CPN"` | `"Trigger Cedola"` | + +La colonna è alla posizione 4 (0-indexed), larghezza corrente 52pt. "Trigger Cedola" a font Small ha larghezza simile a "Trigger CPN" — la larghezza 52pt è sufficiente, non richiede modifica. Da verificare visivamente dopo il build. + +--- + +## 4. Fix footer branding (`PdfTheme.DrawFooter`) + +### Situazione attuale + +Il codice esistente già usa `"Powered by "` (con spazio finale) come testo di prefisso, e calcola la X del link tramite `MeasureString`. Il bug visivo è che `PdfStandardFont.MeasureString` può restituire una larghezza che esclude il trailing space, causando sovrapposizione tra "by" e il link "Smart Roots". + +### Fix + +Aggiungere un offset fisso di **2pt** alla X del link, dopo il valore restituito da `MeasureString`: + +```csharp +// PRIMA: +float prefixWidth = prefixFont.MeasureString(prefixText).Width; +webLink.DrawTextWebLink(g, new PointF(prefixWidth, footerY)); + +// DOPO: +float prefixWidth = prefixFont.MeasureString(prefixText).Width + 2f; +webLink.DrawTextWebLink(g, new PointF(prefixWidth, footerY)); +``` + +--- + +## Files modificati + +| File | Modifica | +|------|----------| +| `CertReports.Syncfusion/Helpers/PdfTheme.cs` | Nuove costanti colore/brush, fix footer offset +2pt | +| `CertReports.Syncfusion/Services/Implementations/AnagraficaSectionRenderer.cs` | Riscrittura `DrawTitle`, helper `DrawInfoBox`, rinomina colonne sottostanti | +| `CertReports.Syncfusion/Services/Implementations/EventiSectionRenderer.cs` | Rinomina colonna "Trigger CPN" → "Trigger Cedola" | + +--- + +## Non in scope + +- Modifiche al grafico, agli scenari, o ad altre sezioni del report +- Modifiche al DB o alle stored procedure +- Modifiche al layout delle sezioni A, B del report (Caratteristiche, Analisi)