.section-intro{font-size:14px;line-height:1.7;color:#374151;margin:0 0 16px}
.guideline-list{margin:0 0 24px;padding-left:20px;font-size:14px;line-height:1.75;color:#374151}
.guideline-list li{margin-bottom:6px}
.guideline-list li:last-child{margin-bottom:0}
.component-preview{border:1px solid #d0d7de;border-radius:8px;overflow:hidden;margin:16px 0 24px}
.component-preview-header{padding:8px 14px;background:#f6f8fa;border-bottom:1px solid #d0d7de;font-size:11px;font-weight:700;color:#6B7280;text-transform:uppercase;letter-spacing:.05em}
.component-preview-canvas{padding:32px;background:#f8f9fa;display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:center;gap:32px}
.wpf-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;font-family:'Segoe UI',system-ui,sans-serif;font-size:12px;font-weight:400;padding:0 16px;border-radius:2px;cursor:default;min-width:75px;height:28px;border:1px solid;white-space:nowrap;box-sizing:border-box}
.wpf-btn-primary{background:#0078D4;border-color:#0067B8;color:#fff}
.wpf-btn-default{background:#FAFAFA;border-color:#8A8A8A;color:#1A1A1A}
.wpf-btn-danger{background:#C50F1F;border-color:#A11112;color:#fff}
.wpf-btn-disabled{background:#F5F5F5;border-color:#C8C8C8;color:#ABABAB;cursor:not-allowed}
.wpf-btn-tertiary{border-color:transparent;background:transparent;color:#0078D4}
.btn-state-label{font-size:11px;color:#666;text-align:center;display:block;margin-top:4px}
.btn-state-group{display:flex;flex-direction:column;align-items:center;gap:4px}
.spec-table{width:100%;border-collapse:collapse;font-size:13px;margin:12px 0 24px}
.spec-table th{text-align:left;padding:8px 12px;background:#F3F4F6;font-weight:700;font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:#6B7280;border-bottom:2px solid #E5E7EB}
.spec-table td{padding:8px 12px;border-bottom:1px solid #F3F4F6;vertical-align:top;line-height:1.5}
.spec-table code{background:#F3F4F6;padding:1px 5px;border-radius:3px;font-size:12px;font-family:Consolas,'Courier New',monospace;color:#9d174d;white-space:nowrap}
.btn-spec-visual{display:flex;flex-direction:column;gap:16px;margin:0 0 32px}
.btn-spec-wireframe{border:1px solid #d0d7de;border-radius:6px;background:#f6f8fa;padding:16px;width:100%;box-sizing:border-box}
.btn-spec-wireframe__title{margin:0 0 12px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:#6B7280}
.btn-spec-wireframe__note{margin:12px 0 0;font-size:12px;line-height:1.55;color:#57606a}
.btn-spec-anatomy{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:24px}
@media(max-width:720px){.btn-spec-anatomy{grid-template-columns:1fr}}
.btn-spec-anatomy__item{min-width:0}
.btn-spec-anatomy__subtitle{margin:0 0 10px;font-size:12px;font-weight:600;color:#0d1117;font-family:'Segoe UI',system-ui,sans-serif}
.btn-spec-annotated{display:flex;align-items:flex-start;gap:10px}
.btn-spec-annotated__dims{display:flex;flex-direction:column;align-items:center;flex-shrink:0;padding-top:0}
.btn-spec-dim{display:flex;flex-direction:column;align-items:center;gap:4px}
.btn-spec-dim--height{height:28px;justify-content:space-between}
.btn-spec-dim--height-sm{height:23px;justify-content:space-between}
.btn-spec-dim__line{background:transparent;border:0;border-left:1px dashed #9ca3af;width:0;flex:1;min-height:8px}
.btn-spec-dim__line--h{width:100%;height:0;border-left:0;border-top:1px dashed #9ca3af;flex:none}
.btn-spec-dim__label{font-size:10px;font-weight:600;line-height:1.2;color:#57606a;font-family:'Segoe UI',system-ui,sans-serif;white-space:nowrap}
.btn-spec-annotated__body{display:flex;flex-direction:column;align-items:flex-start;gap:8px;min-width:0}
.btn-spec-annotated__width{display:flex;flex-direction:column;align-items:center;gap:4px;width:100%;max-width:140px}
.btn-spec-padding{display:flex;align-items:center;gap:4px;margin-top:2px}
.btn-spec-padding__zone{height:28px;border:1px dashed #90D4B3;background:rgba(144,212,179,.15);flex:1;min-width:12px;max-width:24px}
.btn-spec-padding__label{font-size:10px;font-weight:600;color:#1A7F5A;white-space:nowrap;font-family:'Segoe UI',system-ui,sans-serif}
.btn-spec-swatches{display:flex;flex-wrap:wrap;gap:10px;margin-top:4px}
.btn-spec-swatch{display:flex;align-items:center;gap:8px;font-size:11px;line-height:1.4;color:#374151;font-family:'Segoe UI',system-ui,sans-serif}
.btn-spec-swatch__chip{width:28px;height:16px;border:1px solid;border-radius:2px;flex-shrink:0}
.btn-spec-swatch__chip--primary{background:#0078D4;border-color:#0067B8}
.btn-spec-swatch__chip--secondary{background:#FAFAFA;border-color:#8A8A8A}
.btn-spec-swatch__chip--destructive{background:#C50F1F;border-color:#A11112}
.btn-spec-swatch__chip--wpf{background:#e1e1e1;border-color:#ababab}
.btn-spec-swatch__chip--winforms{background:#dddddd;border-color:#ababab}
.btn-spec-swatch code{font-size:10px;font-family:Consolas,'Courier New',monospace;color:#57606a}
.cmdbar-btn{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;height:23px;min-width:75px;padding:0 10px;border:1px solid #ababab;border-radius:2px;background:#e1e1e1;color:#0d1117;font-family:'Segoe UI',system-ui,sans-serif;font-size:12px;font-weight:400;line-height:16px;text-align:center;white-space:nowrap;flex-shrink:0}
.btn-spec-dialog{border:1px solid #d0d7de;border-radius:6px;background:#fff;overflow:hidden}
.btn-spec-dialog__content{min-height:72px;padding:16px;background:#fff;font-size:12px;line-height:1.5;color:#6B7280;font-family:'Segoe UI',system-ui,sans-serif;border-bottom:1px solid #e5e7eb}
.btn-spec-cmdbar{position:relative;display:flex;align-items:center;justify-content:flex-end;box-sizing:border-box;height:40px;padding:0 8px;background:#f0f0f0;border-top:1px solid #d0d7de}
.btn-spec-cmdbar__height{position:absolute;left:12px;top:50%;transform:translateY(-50%);display:flex;align-items:center;gap:6px}
.btn-spec-cmdbar__height-line{width:24px;height:0;border-top:1px dashed #9ca3af}
.btn-spec-cmdbar__height-label{font-size:10px;font-weight:600;color:#57606a;white-space:nowrap;font-family:'Segoe UI',system-ui,sans-serif}
.btn-spec-cmdbar__row{display:flex;align-items:center;gap:0}
.btn-spec-cmdbar__gap{display:flex;align-items:center;justify-content:center;width:8px;flex-shrink:0;height:23px;background:repeating-linear-gradient(90deg,#c5cad0 0,#c5cad0 1px,transparent 1px,transparent 3px)}
.btn-spec-cmdbar__gap-label{font-size:9px;font-weight:600;color:#57606a;background:#f0f0f0;padding:0 2px;line-height:1;font-family:'Segoe UI',system-ui,sans-serif}
.btn-spec-footnote{margin:8px 0 0;font-size:12px;font-style:italic;line-height:1.55;color:#6B7280}
.hint-callout{display:flex;align-items:flex-start;gap:16px;margin:16px 0 24px;padding:16px 20px 16px 16px;background:#eff6ff;border:1px solid #3b82f6;border-left:4px solid #3b82f6;border-radius:6px}
.hint-callout__icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:32px;min-width:32px;height:32px;font-size:20px;line-height:1;margin:2px 0 0}
.hint-callout__content{flex:1;min-width:0}
.hint-callout__title{margin:0 0 6px;font-size:13px;font-weight:700;color:#0d1117}
.hint-callout__body{margin:0;font-size:13px;line-height:1.75;color:#57606a}
.hint-callout__body code{background:#F3F4F6;padding:1px 5px;border-radius:3px;font-size:12px;font-family:Consolas,'Courier New',monospace;color:#9d174d}
.do-dont-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;margin:16px 0;align-items:stretch}
@media(max-width:900px){.do-dont-grid{grid-template-columns:1fr}}
.do-dont-card{border-radius:8px;overflow:hidden;border:1px solid;display:flex;flex-direction:column;min-width:0;background:#fff;height:100%}
.do-card{border-color:#90D4B3}
.dont-card{border-color:#F0A898}
.do-dont-label{display:flex;align-items:center;gap:6px;padding:8px 14px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.07em}
.do-card .do-dont-label{background:#F0FAF6;color:#1A7F5A}
.dont-card .do-dont-label{background:#FFF5F4;color:#B91C1C}
.do-dont-content{padding:14px;font-size:13px;color:#374151;line-height:1.6;border-top:1px solid;flex:1}
.do-card .do-dont-content{border-color:#90D4B3}
.dont-card .do-dont-content{border-color:#F0A898}
kbd{display:inline-block;padding:1px 6px;font-size:11px;font-family:Consolas,'Courier New',monospace;background:#f6f8fa;border:1px solid #d0d7de;border-radius:4px;box-shadow:inset 0 -1px 0 #d0d7de}
.xaml-tabs{margin:20px 0;border:1px solid #d0d7de;border-radius:8px;background:#fff;max-width:100%;box-sizing:border-box;overflow:visible}
.xaml-tabs .tab-list{display:flex;flex-wrap:wrap;align-items:stretch;background:#f6f8fa;border-bottom:1px solid #d0d7de;border-radius:8px 8px 0 0;margin:0;padding:0;overflow:visible}
.xaml-tabs .tab-btn{font-family:'Segoe UI',system-ui,sans-serif;font-size:13px;font-weight:500;color:#6B7280;padding:10px 16px;border:none!important;border-bottom:2px solid transparent;background:transparent;transition:color .15s,border-color .15s,background .15s;white-space:nowrap;cursor:pointer;flex:0 0 auto;flex-shrink:0;width:auto!important;max-width:none!important;appearance:none;-webkit-appearance:none;box-sizing:border-box;line-height:1.4;margin:0;min-height:42px;box-shadow:none!important}
.xaml-tabs .tab-btn:hover{color:#0d1117;background:#eef2f6}
.xaml-tabs .tab-btn.active{color:#0078d4;border-bottom-color:#0078d4;background:#fff}
.xaml-tabs .tab-panel{display:none;padding:20px;margin:0;min-height:320px;box-sizing:border-box;background:#fff}
.xaml-tabs .tab-panel.active{display:block}
.xaml-tabs .code-block{margin:0;border-radius:6px;overflow:hidden;border:none;background:#1A1A2E;display:flex;flex-direction:column;height:100%}
.code-block-header{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;background:#13132A;border-bottom:1px solid rgba(255,255,255,.08);flex-shrink:0}
.code-lang{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:rgba(255,255,255,.45)}
.code-copy{font-family:'Segoe UI',system-ui,sans-serif;font-size:11px;color:rgba(255,255,255,.45);padding:2px 8px;border-radius:4px;cursor:pointer;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.12);width:auto!important;flex-shrink:0;box-shadow:none!important}
.code-copy:hover{background:rgba(255,255,255,.12);color:rgba(255,255,255,.75)}
.code-copy.copied{color:#47B37F;border-color:#47B37F}
.xaml-tabs .code-block pre{margin:0;padding:20px 18px;overflow:auto;scrollbar-width:thin;flex:1 1 auto;box-sizing:border-box;white-space:normal!important}
.xaml-tabs .code-block code{font-family:Consolas,'Courier New',monospace;font-size:13px;line-height:1.65;color:#ABB2BF;background:none!important;border:none!important;padding:0!important;white-space:normal!important;display:block}
.xaml-tabs .code-line{display:block;white-space:pre;min-height:1.65em}
.tok-comment{color:#5C6370;font-style:italic}
.tok-attr{color:#E06C75}
.tok-tag{color:#E06C75}
.tok-string{color:#98C379}
.related-pages{margin-top:32px;padding-top:20px;border-top:1px solid #E5E7EB}
.related-pages h3{font-size:13px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:#6B7280;margin-bottom:10px}

# Buttons

Button types, visual states, sizes, keyboard behavior, and XAML implementation for WPF and WinForms.
## Button types

Petrel Classic defines four button types. Choose based on the importance of the action and its context within the UI.
Live preview — Button types
Apply
Primary
Cancel
Secondary
Reset
Tertiary
Delete
Destructive
Calculate
Disabled
Type
When to use
Limit per context
Primary
The single most important action in a dialog or panel — "Apply", "Save", "Run"
Maximum 1 per dialog/panel
Secondary
Supporting actions that are less important than the primary — "Cancel", "Back", "Preview"
2–3 per context
Tertiary
Low-emphasis actions — "Reset to defaults", "Learn more", links within toolbars
No strict limit
Destructive
Actions that delete or remove data. Requires confirmation dialog before executing.
1 per action group
## Visual states

Every button must implement all visual states. The focus state is accessibility-critical — it must be visible in all themes including High Contrast.
Primary button — All states
Default
Default
Hover
Hover
Pressed
Pressed
Focused
Focused
Disabled
Disabled
State
Primary bg
Primary fg
Secondary bg
Default
#0078D4
#FFFFFF
#FAFAFA
, border 
#8A8A8A
Hover
#106EBE
#FFFFFF
#E8F2FC
, border 
#0078D4
Pressed
#005A9E
#FFFFFF
#CCE2F8
, border 
#005A9E
Focused
Same as default
—
—
Disabled
#F5F5F5
#ABABAB
#F5F5F5
, border 
#C8C8C8
## Sizes

Size
Height
Padding (H)
Font size
Use
Small
24px
8px
11px
Toolbar inline actions, compact panels
Medium (default)
28px
16px
12px
Dialogs, property panels
Large
36px
20px
14px
Primary dialogs, landing pages, wizard steps
## Button measurements

Styled Petrel buttons use the medium default size (28px). Dialog command bars use system-default buttons at 23px height — see the command bar wireframe below and the 
Dialogs
page for full placement rules.
Styled button — medium default (28px)
Label button — centered text
28px
Apply changes
min 75px
16px
Icon-only button
28px
+
28px
Primary 
#0078D4
Secondary 
#FAFAFA
Destructive 
#C50F1F
Use Petrel button styles for typed actions. Alignment is centered within the button bounds.
Dialog command bar — system-default buttons (23px)
Dialog content area
40px
Cancel
8px
OK
8px
Command bar buttons use system defaults at 23px height. Spacing between buttons is 8px; the rightmost button sits 8px from the dialog edge. Command bar background is 
#F0F0F0
. WPF default background 
#E1E1E1
, WinForms 
#DDDDDD
.
Specification reference
Property
Styled button (medium)
Command bar button
Height
28px
23px
Minimum width (with label)
75px; 16px horizontal padding
75px; 5–15px whitespace on either side of label
Minimum width (icon only)
28px
23px
Alignment
Centered
Centered
Spacing between buttons
—
8px
Right edge inset
—
8px from rightmost button to dialog edge
Command bar height
—
40px
Command bar background
—
#F0F0F0
All values are at 100% DPI; scale proportionally with DPI scaling.
## Keyboard interaction

Space
or 
Enter
— Activate the focused button (equivalent to a click)
Tab
— Move focus to the next focusable element
Shift+Tab
— Move focus to the previous focusable element
Esc
in a dialog — Equivalent to clicking Cancel (the secondary/close action)
The default button in a dialog (typically the primary action) should respond to 
Enter
at the dialog level — configure this with 
IsDefault="True"
on the Button element.
💡
IsDefault and IsCancel in WPF
Set 
IsDefault="True"
on the primary button to make 
Enter
activate it from anywhere in the dialog. Set 
IsCancel="True"
on the Cancel button to make 
Esc
activate it. Only one button of each type per window.
## Do and Don't

✓ Do
Use sentence case for button labels: "Apply changes", "Delete well", "Open file". Sentence case is more readable and consistent with Windows conventions.
✗ Don't
Don't use all-caps labels ("APPLY", "DELETE") or vague labels ("OK", "Yes/No" without context). Screen readers announce button labels — "Yes" is meaningless without context.
✓ Do
Set 
AutomationProperties.Name
on icon-only buttons. The accessible name must describe the action, not the icon's visual appearance.
✗ Don't
Don't use a generic tooltip for the accessible name. 
ToolTip="Pencil icon"
is not helpful. Use 
AutomationProperties.Name="Edit well name"
instead.
## Accessibility

Every button must have a visible, distinct focus indicator. Do not suppress the WPF focus rectangle or use 
FocusVisualStyle="{x:Null}"
without providing a custom focus ring.
Minimum contrast ratio of 3:1 between the button border/fill and its background for UI component contrast (WCAG 1.4.11).
Button text must have 4.5:1 contrast against the button background.
Disabled buttons are exempt from contrast requirements but must not be confused with enabled buttons — use opacity reduction of at most 60%.
Set 
AutomationProperties.Name
explicitly for all icon-only buttons.
## XAML Implementation

Primary
Secondary
Icon Button
Destructive
XAML — Primary Button
Copy
<
Button
Style
=
"{DynamicResource PetrelPrimaryButtonStyle}"
IsDefault
=
"True"
Content
=
"Apply changes"
Command
=
"{Binding ApplyCommand}"
MinWidth
=
"80"
Height
=
"28"
/
>
XAML — Secondary Button
Copy
<
Button
Style
=
"{DynamicResource PetrelSecondaryButtonStyle}"
IsCancel
=
"True"
Content
=
"Cancel"
Command
=
"{Binding CancelCommand}"
MinWidth
=
"80"
Height
=
"28"
/
>
XAML — Icon-only Button (with accessible name)
Copy
<
Button
Style
=
"{DynamicResource PetrelIconButtonStyle}"
AutomationProperties.Name
=
"Edit well name"
ToolTip
=
"Edit well name"
Width
=
"28"
Height
=
"28"
>
<
Image
Source
=
"{DynamicResource EditIcon}"
Width
=
"16"
Height
=
"16"
AutomationProperties.AccessibilityView
=
"Raw"
/
>
<
/Button
>
XAML — Destructive Button with Confirmation
Copy
<
!-- Button triggers a confirmation dialog before executing --
>
<
Button
Style
=
"{DynamicResource PetrelDestructiveButtonStyle}"
Content
=
"Delete well"
Command
=
"{Binding RequestDeleteCommand}"
/
>
<
!-- ViewModel: RequestDeleteCommand shows confirm dialog
before executing DeleteCommand (two-step pattern) --
>
(function () {
  document.querySelectorAll('.xaml-tabs').forEach(function (tabs) {
    var btns = tabs.querySelectorAll('.tab-btn');
    var panels = tabs.querySelectorAll('.tab-panel');
    btns.forEach(function (btn, i) {
      btn.addEventListener('click', function () {
        btns.forEach(function (b) {
          b.classList.remove('active');
          b.setAttribute('aria-selected', 'false');
        });
        panels.forEach(function (p) { p.classList.remove('active'); });
        btn.classList.add('active');
        btn.setAttribute('aria-selected', 'true');
        if (panels[i]) panels[i].classList.add('active');
      });
    });
  });

  document.querySelectorAll('.xaml-tabs .code-copy').forEach(function (btn) {
    btn.addEventListener('click', function () {
      var pre = btn.closest('.code-block') && btn.closest('.code-block').querySelector('pre');
      if (!pre || !navigator.clipboard) return;
      var text = Array.from(pre.querySelectorAll('.code-line')).map(function (line) {
        return line.textContent.replace(/\u00a0/g, ' ').replace(/\s+$/,'');
      }).join('\n').trim();
      navigator.clipboard.writeText(text).then(function () {
        btn.textContent = 'Copied!';
        btn.classList.add('copied');
        window.setTimeout(function () {
          btn.textContent = 'Copy';
          btn.classList.remove('copied');
        }, 2000);
      });
    });
  });
})();

### Related pages

Dialogs
— Button placement in dialog command bars
Keyboard and focus
— Focus management requirements
Color 
&
Contrast
— Button colour tokens
Ribbon
— Ribbon command buttons