As others have pointed out, you're calling Substring with incorrect values. It takes a starting position and a length (and you're passing in an end position).
However, a different way to approach this problem might be to write a method that generates a sign for you, with specific text and a specific width, and then you can simply call that method as many times as you like to generate equal-sized signs.
If we write a method that takes in a string and a width, we can generate a sign accordingly. One question that occurs quickly, however, is what do we do if the string is longer than the width? I think there are two options:
- Truncate the string to fit the width
- Expand the sign to fit the string
So I've added an expandWidth parameter that, when set to true, expands the sign to accommodate the longest string. If set to false, it will truncate the string.
The rest of the method is fairly self-explanatory: Split the input string on the newline characters in case the sign should have more than one line, determine the longest line we need to display and adjust our sign width if expandWidth is true, write out our header string (the top of the sign), use Substring, PadLeft, and PadRight to center each line within the width, and finally write our footer  (the bottom of the sign):
public static void  WriteSign(string signText, int signWidth = 10, bool expandWidth = true)
{
    // Split input into lines, in case there's 
    // more than one line to display on the sign
    var lines = signText
        .Split(new[] {'\r', '\n'}, StringSplitOptions.None)
        .Select(line => line.Trim());
    // Determine the sign width based on the longest line
    var actualSignWidth = expandWidth 
        ? Math.Max(lines.Max(l => l.Length), signWidth) 
        : signWidth;
    // Write header
    Console.WriteLine("╔" + new string('═', Math.Max(0, actualSignWidth)) + "╗");
    // Write lines
    foreach (var line in lines)
    {
        var signLine = line.Substring(0, Math.Min(line.Length, actualSignWidth))
        .PadLeft(Math.Min(actualSignWidth, (actualSignWidth + line.Length) / 2))
        .PadRight(actualSignWidth);
        Console.WriteLine("║" + signLine + "║");
    }
    // Write footer
    Console.WriteLine("╚" + new string('═', Math.Max(0, actualSignWidth)) + "╝");
}
Now we can create a string with \n characters between each group of words, and we can display them all on one sign, or split them and display a bunch of separate signs.
For example:
private static void Main(string[] cmdArgs)
{
    var signText = "If our road signs\nCatch your eye\nSmile\nBut don't forget\nTo buy\nBurma shave";
    var splitText = signText.Split('\n');
    var signWidth = splitText.Max(line => line.Length) + 2;
    // Write a sign with all the lines on one sign
    WriteSign(signText, signWidth);
    // Write a divider to separate the first sign from the rest
    Console.WriteLine(new string('-', Console.WindowWidth));
    // Write a separate sign for each line
    foreach (var line in splitText) WriteSign(line, signWidth);
    GetKeyFromUser("\nDone! Press any key to exit...");
}
Output
